自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Style在Android中的繼承關(guān)系

移動(dòng)開(kāi)發(fā) Android
Android的Styles(樣式)和Themes(主題)非常類(lèi)似Web開(kāi)發(fā)里的CSS,方便開(kāi)發(fā)者將頁(yè)面內(nèi)容和布局呈現(xiàn)分開(kāi)。Style和Theme在Android里的定義方式是完全一樣的,兩者只是概念上的區(qū)別:Style作用在單個(gè)視圖或控件上,而Theme用于Activity或整個(gè)應(yīng)用程序。由于作用范圍的不同,Theme也就需要比Style包含更多的定義屬性值的項(xiàng)目(item)。

[[182651]]

Android的Styles(樣式)和Themes(主題)非常類(lèi)似Web開(kāi)發(fā)里的CSS,方便開(kāi)發(fā)者將頁(yè)面內(nèi)容和布局呈現(xiàn)分開(kāi)。Style和Theme在Android里的定義方式是完全一樣的,兩者只是概念上的區(qū)別:Style作用在單個(gè)視圖或控件上,而Theme用于Activity或整個(gè)應(yīng)用程序。由于作用范圍的不同,Theme也就需要比Style包含更多的定義屬性值的項(xiàng)目(item)。不過(guò)本文,我將Style和Theme都?xì)w為Style來(lái)稱(chēng)呼。

Android的Style和Web的CSS相比,有一個(gè)缺陷就是只能針對(duì)一個(gè)對(duì)象只能通過(guò)android:theme="@style/AppTheme"或style="@style/MyStyle"指定一個(gè)值。而CSS則可以通過(guò)class屬性在DOM元素上定義多個(gè)樣式來(lái)達(dá)到組合的效果。不過(guò)Style也有CSS沒(méi)有的功能,那就是繼承(Inheritance)。(當(dāng)然CSS通過(guò)LESS和SASS這些工具也獲得繼承的能力。)

Style繼承簡(jiǎn)介

根據(jù)Android Developers官方文檔的介紹,定義Style的繼承有兩種方式:一是通過(guò)parent標(biāo)志父Style;

  1. <style name="GreenText" parent="@android:style/TextAppearance" 
  2.     <item name="android:textColor">#00FF00</item>  
  3. </style>  

另一種則是將父Style的名字作為前綴,然后通過(guò)“.”連接新定義Style的名字:

  1. <style name="CodeFont.Red"
  2. <item name="android:textColor">#FF0000</item> 
  3. </style>  

第二種方式可以***連接子Style來(lái)實(shí)踐多層繼承:

  1. <style name="CodeFont.Red.Big"
  2. <item name="android:textSize">30sp</item> 
  3. </style>  

相對(duì)***種,Android對(duì)第二種方式做出的限制就是Style必須是由自己定義的,或者說(shuō)父Style和子Style必須是定義在同一個(gè)程序內(nèi),不能是引用第三方或系統(tǒng)的Style。畢竟對(duì)于系統(tǒng)的Style的引用是需要加上android:前綴作為命名空間。

其次在使用Style時(shí),對(duì)于第二種方式定義的Style,必須引用其完全的名字,也就是說(shuō)必須要包含完整的前綴和名字:

  1. <EditText 
  2. style="@style/CodeFont.Red.Big" 
  3. ... />  

Android對(duì)于***種定義方式并沒(méi)用限制,所以所有以第二種方式定義的Style都可以轉(zhuǎn)用***種:

  1. <style name="Big" parent="CodeFont.Red"
  2. <item name="android:textSize">30sp</item> 
  3. </style>  

只要parent中的名字對(duì)應(yīng)上實(shí)際定義的Style名字即可。不過(guò)換成***種后Style的名字如果太簡(jiǎn)潔就容易沖突了。

兩種繼承方式混合的效果

前面說(shuō)到Style的兩種繼承方式的效果是一致的,那假如將兩種方式混在一起定義一個(gè)Style又會(huì)是什么樣的效果呢?下邊就用實(shí)際例子來(lái)分析一下。

首先定義一些實(shí)驗(yàn)所需的自定義屬性(attr),(這樣可以減少系統(tǒng)屬性的干擾,因?yàn)橄到y(tǒng)總是會(huì)為它的屬性定義值,那樣可能無(wú)法分辨***的效果是來(lái)自系統(tǒng)還是定義的值)

  1. <?xml version="1.0" encoding="utf-8"?> 
  2.  
  3. <resources> 
  4.  
  5.     <declare-styleable name="CustomStyle"
  6.  
  7.         <attr name="customColor" format="color"/> 
  8.  
  9.         <attr name="customText" format="string"/> 
  10.  
  11.         <attr name="customSize" format="dimension"/> 
  12.  
  13.     </declare-styleable> 
  14.  
  15. </resources>  

接著定義一個(gè)TextView的子類(lèi),并在其中獲取上邊自定義屬性的值并賦予TextView去呈現(xiàn):

  1. import android.util.TypedValue; 
  2.  
  3. import android.widget.TextView; 
  4.  
  5. /** 
  6.  
  7. * @author Ider 
  8.  
  9. */ 
  10.  
  11. public class StyledTextView extends TextView { 
  12.  
  13.     public StyledTextView(Context context) { 
  14.  
  15.         this(context, null); 
  16.  
  17.     } 
  18.  
  19.     public StyledTextView(Context context, AttributeSet attrs) { 
  20.  
  21.         this(context, attrs, 0); 
  22.  
  23.     } 
  24.  
  25.     public StyledTextView(Context context, AttributeSet attrs, int defStyleAttr) { 
  26.  
  27.         super(context, attrs, defStyleAttr); 
  28.  
  29.         final TypedArray a = context.getTheme() 
  30.  
  31.                 .obtainStyledAttributes(attrs, R.styleable.CustomStyle, defStyleAttr, 0); 
  32.  
  33.         final CharSequence text = a.getText(R.styleable.CustomStyle_customText); 
  34.  
  35.         final int color = a.getColor(R.styleable.CustomStyle_customColor, Color.RED); 
  36.  
  37.         final float size = a.getDimensionPixelSize(R.styleable.CustomStyle_customSize, 70); 
  38.  
  39.         a.recycle(); 
  40.  
  41.         setText(text); 
  42.  
  43.         setTextColor(color); 
  44.  
  45.         setTextSize(TypedValue.COMPLEX_UNIT_PX, size); 
  46.  
  47.     } 
  48.  
  49.  

然后就是定義研究所需的Style

  1. <resources> 
  2.  
  3.     <style name="SuperStyleOne"
  4.  
  5.         <item name="customColor">@android:color/holo_orange_dark</item> 
  6.  
  7.         <item name="customText">Hello World</item> 
  8.  
  9.         <item name="customSize">30dp</item> 
  10.  
  11.     </style> 
  12.  
  13.     <style name="SuperStyleTwo"
  14.  
  15.         <item name="customText">www.iderzheng.com</item> 
  16.  
  17.     </style> 
  18.  
  19.     <style name="SuperStyleOne.SubOne"
  20.  
  21.         <item name="customColor">@android:color/holo_blue_dark</item> 
  22.  
  23.     </style> 
  24.  
  25.     <style name="SuperStyleOne.SubTwo" parent="SuperStyleTwo"
  26.  
  27.     </style> 
  28.  
  29.     <style name="SuperStyleOne.SubThree" parent="SuperStyleTwo"
  30.  
  31.         <item name="customText">blog.iderzheng.com</item> 
  32.  
  33.     </style> 
  34.  
  35. </resources>  

上邊定義的Style里,SuperStyleOne將通過(guò)添加前綴的方式作用到子Style上,而SuperStyleTwo則通過(guò)指定到parent來(lái)其作用??梢钥吹絊ubTwo和SubThree混合了兩種方式。

***在Activity的布局視圖里使用自定類(lèi)并設(shè)定上不同的Style

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  2.  
  3.               xmlns:tools="http://schemas.android.com/tools" 
  4.  
  5.               android:orientation="vertical" 
  6.  
  7.               android:layout_width="match_parent" 
  8.  
  9.               android:layout_height="match_parent" 
  10.  
  11.               android:paddingLeft="@dimen/activity_horizontal_margin" 
  12.  
  13.               android:paddingRight="@dimen/activity_horizontal_margin" 
  14.  
  15.               android:paddingTop="@dimen/activity_vertical_margin" 
  16.  
  17.               android:paddingBottom="@dimen/activity_vertical_margin" 
  18.  
  19.               tools:context=".MainActivity"
  20.  
  21.     <com.ider.trial.styles.StyledTextView 
  22.  
  23.             style="@style/SuperStyleOne" 
  24.  
  25.             android:layout_width="wrap_content" 
  26.  
  27.             android:layout_height="wrap_content"/> 
  28.  
  29.     <com.ider.trial.styles.StyledTextView 
  30.  
  31.             style="@style/SuperStyleOne.SubOne" 
  32.  
  33.             android:layout_width="wrap_content" 
  34.  
  35.             android:layout_height="wrap_content"/> 
  36.  
  37.     <com.ider.trial.styles.StyledTextView 
  38.  
  39.             style="@style/SuperStyleOne.SubTwo" 
  40.  
  41.             android:layout_width="wrap_content" 
  42.  
  43.             android:layout_height="wrap_content"/> 
  44.  
  45.     <com.ider.trial.styles.StyledTextView 
  46.  
  47.             style="@style/SuperStyleOne.SubThree" 
  48.  
  49.             android:layout_width="wrap_content" 
  50.  
  51.             android:layout_height="wrap_content"/> 
  52.  
  53. </LinearLayout>  

運(yùn)行之后得到效果如下: 

 

 

 

***個(gè)和第二個(gè)都是Style標(biāo)準(zhǔn)的使用方式,也看到它們正確地獲得了定義的屬性值,子Style也正確的繼承和覆蓋了父Style的屬性值。

對(duì)于第三個(gè)和第四個(gè),它們呈現(xiàn)的顏色是代碼中使用的默認(rèn)紅色(Color.RED),字體的值也是源自代碼中的使用值,所以明顯比前兩者要小。這也就是說(shuō)它們并沒(méi)用繼承下SuperStyleOne中定義的字體大小和顏色。但是SuperStyleTwo中定義的內(nèi)容被第三個(gè)正確的顯示了出來(lái),也說(shuō)明SubTwo成功繼承通過(guò)parent指定的父Style的內(nèi)容。而第四個(gè)呈現(xiàn)出來(lái)內(nèi)容則說(shuō)明覆蓋的效果也是正確的。

在做這個(gè)試驗(yàn)之前,我一直以為兩種方式會(huì)同時(shí)其作用,只是用parent指定比用前綴有高優(yōu)先級(jí)。也就是說(shuō)Android會(huì)先從當(dāng)前Style定義中找某個(gè)屬性的值,如果沒(méi)有找到就轉(zhuǎn)到parent指定的父Style中找,還沒(méi)有則轉(zhuǎn)到前綴指定的父Style中找。但是通過(guò)上邊的結(jié)果表明:當(dāng)使用parent指定父Style后,前綴方式則不在其作用,只是作為Style的名字。也就是說(shuō):Android的Style不支持多繼承。Style的繼承只能單線一層層下來(lái)。

反過(guò)來(lái)在看看系統(tǒng)定義的Style也更容易懂了,比如打開(kāi)themes_holo.xml,會(huì)看到很多一樣的內(nèi)容被”冗余”地定義在Theme.Holo和Theme.Holo.Light兩個(gè)Style下。但因?yàn)門(mén)heme.Holo.Light用parent指定了其父Style是Theme.Light,所以Theme.Holo.Light并沒(méi)有從Theme.Holo繼承任何屬性值,也因此這樣的冗余是必須的。

  1. <style name="Theme.Holo.Light" parent="Theme.Light"
  2.  
  3. ... ... ... ... 
  4.  
  5. </style>  

使用Theme.Holo.Light作為Style的名字只是為了名字更加的清晰明了。

References:

  1. Styles and Themes | Android Developers
  2. Android XML theme inheriting from two parent themes? – Stack Overflow
  3. xml – Reason why style attribute does not use the android: namespace prefix – Stack Overflow 
責(zé)任編輯:龐桂玉 來(lái)源: 安卓開(kāi)發(fā)精選
相關(guān)推薦

2009-07-02 09:40:14

Hibernate的繼

2022-03-21 15:11:17

Java繼承初始化

2009-06-02 10:28:36

JPA繼承類(lèi)Netbeans

2010-06-18 15:15:13

UML

2011-08-08 09:51:52

Cocoa 框架 類(lèi)

2009-09-18 13:40:40

繼承關(guān)系

2010-08-24 14:10:44

div style

2010-01-19 18:51:17

C++類(lèi)

2013-03-04 11:10:03

JavaJVM

2009-09-25 14:12:16

Hibernate繼承

2023-05-09 12:42:51

Java繼承多態(tài)

2010-08-09 14:01:22

關(guān)系法則

2010-08-25 13:48:51

CSSlist-style-

2012-05-30 15:03:43

ibmdw

2022-12-26 00:00:03

非繼承關(guān)系JDK

2025-01-13 00:00:00

MapStruct繼承關(guān)系Java

2022-10-14 16:18:40

MobileNetAndroid端模型訓(xùn)練

2009-08-03 18:46:38

Silverlight

2010-07-08 10:33:34

UML接口

2024-10-09 07:59:10

C#接口信息
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)