您好,登錄后才能下訂單哦!
本篇內容主要講解“Style在Android中的繼承關系是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Style在Android中的繼承關系是什么”吧!
Android的Styles(樣式)和Themes(主題)非常類似Web開發里的CSS,方便開發者將頁面內容和布局呈現分開。Style和Theme在Android里的定義方式是完全一樣的,兩者只是概念上的區別:Style作用在單個視圖或控件上,而Theme用于Activity或整個應用程序。由于作用范圍的不同,Theme也就需要比Style包含更多的定義屬性值的項目(item)。不過本文,我將Style和Theme都歸為Style來稱呼。
Android的Style和Web的CSS相比,有一個缺陷就是只能針對一個對象只能通過android:theme="@style/AppTheme"或style="@style/MyStyle"指定一個值。而CSS則可以通過class屬性在DOM元素上定義多個樣式來達到組合的效果。不過Style也有CSS沒有的功能,那就是繼承(Inheritance)。(當然CSS通過LESS和SASS這些工具也獲得繼承的能力。)
Style繼承簡介
根據Android Developers官方文檔的介紹,定義Style的繼承有兩種方式:一是通過parent標志父Style;
<style name="GreenText" parent="@android:style/TextAppearance"> <item name="android:textColor">#00FF00</item> </style>
另一種則是將父Style的名字作為前綴,然后通過“.”連接新定義Style的名字:
<style name="CodeFont.Red"> <item name="android:textColor">#FF0000</item> </style>
第二種方式可以***連接子Style來實踐多層繼承:
<style name="CodeFont.Red.Big"> <item name="android:textSize">30sp</item> </style>
相對***種,Android對第二種方式做出的限制就是Style必須是由自己定義的,或者說父Style和子Style必須是定義在同一個程序內,不能是引用第三方或系統的Style。畢竟對于系統的Style的引用是需要加上android:前綴作為命名空間。
其次在使用Style時,對于第二種方式定義的Style,必須引用其完全的名字,也就是說必須要包含完整的前綴和名字:
<EditText style="@style/CodeFont.Red.Big" ... />
Android對于***種定義方式并沒用限制,所以所有以第二種方式定義的Style都可以轉用***種:
<style name="Big" parent="CodeFont.Red"> <item name="android:textSize">30sp</item> </style>
只要parent中的名字對應上實際定義的Style名字即可。不過換成***種后Style的名字如果太簡潔就容易沖突了。
兩種繼承方式混合的效果
前面說到Style的兩種繼承方式的效果是一致的,那假如將兩種方式混在一起定義一個Style又會是什么樣的效果呢?下邊就用實際例子來分析一下。
首先定義一些實驗所需的自定義屬性(attr),(這樣可以減少系統屬性的干擾,因為系統總是會為它的屬性定義值,那樣可能無法分辨***的效果是來自系統還是定義的值)
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomStyle"> <attr name="customColor" format="color"/> <attr name="customText" format="string"/> <attr name="customSize" format="dimension"/> </declare-styleable> </resources>
接著定義一個TextView的子類,并在其中獲取上邊自定義屬性的值并賦予TextView去呈現:
import android.util.TypedValue; import android.widget.TextView; /** * @author Ider */ public class StyledTextView extends TextView { public StyledTextView(Context context) { this(context, null); } public StyledTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public StyledTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); final TypedArray a = context.getTheme() .obtainStyledAttributes(attrs, R.styleable.CustomStyle, defStyleAttr, 0); final CharSequence text = a.getText(R.styleable.CustomStyle_customText); final int color = a.getColor(R.styleable.CustomStyle_customColor, Color.RED); final float size = a.getDimensionPixelSize(R.styleable.CustomStyle_customSize, 70); a.recycle(); setText(text); setTextColor(color); setTextSize(TypedValue.COMPLEX_UNIT_PX, size); } }
然后就是定義研究所需的Style
<resources> <style name="SuperStyleOne"> <item name="customColor">@android:color/holo_orange_dark</item> <item name="customText">Hello World</item> <item name="customSize">30dp</item> </style> <style name="SuperStyleTwo"> <item name="customText">www.iderzheng.com</item> </style> <style name="SuperStyleOne.SubOne"> <item name="customColor">@android:color/holo_blue_dark</item> </style> <style name="SuperStyleOne.SubTwo" parent="SuperStyleTwo"> </style> <style name="SuperStyleOne.SubThree" parent="SuperStyleTwo"> <item name="customText">blog.iderzheng.com</item> </style> </resources>
上邊定義的Style里,SuperStyleOne將通過添加前綴的方式作用到子Style上,而SuperStyleTwo則通過指定到parent來其作用。可以看到SubTwo和SubThree混合了兩種方式。
***在Activity的布局視圖里使用自定類并設定上不同的Style
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <com.ider.trial.styles.StyledTextView style="@style/SuperStyleOne" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <com.ider.trial.styles.StyledTextView style="@style/SuperStyleOne.SubOne" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <com.ider.trial.styles.StyledTextView style="@style/SuperStyleOne.SubTwo" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <com.ider.trial.styles.StyledTextView style="@style/SuperStyleOne.SubThree" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
運行之后得到效果如下:
***個和第二個都是Style標準的使用方式,也看到它們正確地獲得了定義的屬性值,子Style也正確的繼承和覆蓋了父Style的屬性值。
對于第三個和第四個,它們呈現的顏色是代碼中使用的默認紅色(Color.RED),字體的值也是源自代碼中的使用值,所以明顯比前兩者要小。這也就是說它們并沒用繼承下SuperStyleOne中定義的字體大小和顏色。但是SuperStyleTwo中定義的內容被第三個正確的顯示了出來,也說明SubTwo成功繼承通過parent指定的父Style的內容。而第四個呈現出來內容則說明覆蓋的效果也是正確的。
在做這個試驗之前,我一直以為兩種方式會同時其作用,只是用parent指定比用前綴有高優先級。也就是說Android會先從當前Style定義中找某個屬性的值,如果沒有找到就轉到parent指定的父Style中找,還沒有則轉到前綴指定的父Style中找。但是通過上邊的結果表明:當使用parent指定父Style后,前綴方式則不在其作用,只是作為Style的名字。也就是說:Android的Style不支持多繼承。Style的繼承只能單線一層層下來。
反過來在看看系統定義的Style也更容易懂了,比如打開themes_holo.xml,會看到很多一樣的內容被”冗余”地定義在Theme.Holo和Theme.Holo.Light兩個Style下。但因為Theme.Holo.Light用parent指定了其父Style是Theme.Light,所以Theme.Holo.Light并沒有從Theme.Holo繼承任何屬性值,也因此這樣的冗余是必須的。
<style name="Theme.Holo.Light" parent="Theme.Light"> ... ... ... ... </style>
使用Theme.Holo.Light作為Style的名字只是為了名字更加的清晰明了。
到此,相信大家對“Style在Android中的繼承關系是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。