深入理解Android View的構(gòu)造函數(shù)

作者ivm

原文地址:http://blog.danlew.net/2016/07/19/a-deep-dive-into-android-view-constructors/

寫在前面的話:我是翻譯國外大神的??赡苡行┓g不是很好,感興趣的可以看看原文,文章寫得挺好的

我經(jīng)??吹紸ndroid View構(gòu)造函數(shù)的混亂。 為什么有四個? 每個參數(shù)做什么? 我需要實現(xiàn)哪些構(gòu)造函數(shù)?

如果你只想要快速,實用的建議,這里有幾個很好的指導(dǎo)方針:

1.使用View(Context)在代碼中創(chuàng)建Views。

2.在重寫方法(Context,AttributeSet)里在從XML加載view

3.忽略其余因為你可能不需要它們

接下來。讓我們深入研究吧!

構(gòu)造函數(shù)參數(shù)

最多可以有四個構(gòu)造函數(shù)。簡要總結(jié):

1.Context- 上下文,用于view 所有地方

2.AttributeSet - XML屬性(從XML加載時)

3.int defStyleAttr - 應(yīng)用于View(在主題中定義)的默認(rèn)樣式

4.int defStyleResource - 如果defStyleAttr未使用,則應(yīng)用于View的默認(rèn)樣式。

除了上下文外,其他參數(shù)僅用于根據(jù)XML屬性(從布局,樣式和主題)配置視圖的初始狀態(tài)。

屬性

們先來談?wù)勀闳绾味x有效的XML屬性。這是XML中的基本ImageView

你有沒有想過layout_width,layout_height和src來自哪里?這不是來自于空氣;您實際上將這些屬性聲明為系統(tǒng)應(yīng)通<declare-styleable>過處理的東西。

每個聲明樣式都會生成一個 R.styleable.[name] 加上另外一個R.styleable.[name]_[attribute],例如,以上生成 R.styleable.ImageView 和 R.styleable.ImageView_src。

這些資源是什么?R.styleable.[name] 是所有屬性資源的數(shù)組,系統(tǒng)用于查找屬性值。每個R.styleable.[name]_[attribute]只是該數(shù)組中的一個索引,因此您可以一次檢索所有屬性,然后單獨查找每個值。

你可以把它想象成一個游標(biāo),將 R.styleable.[name] 作為列查詢,和每個R.styleable.[name]_[attribute] 作為列索引

傳送門:官方文檔

AttributeSet(屬性集)

xml 就是我們寫給view的屬性集

通常你不直接訪問AttributeSet,而是使用Theme.obtainStyledAttributes()。這是因為原始屬性通常需要解析引用并應(yīng)用樣式。例如,如果您在XML中定義style = @ style / MyStyle,則此方法可解析MyStyle,并將其屬性添加到混合中。最后,getsStyledAttributes()返回一個TypedArray,您可以使用它來訪問屬性。

大大簡化了,過程如下:

在這種情況下,我們傳遞兩個參數(shù)來獲取StateedAttributes()。第一個是AttributeSet attrs,來自XML的屬性。第二個是數(shù)組R.styleable.ImageView,它告訴方法我們要提取哪些屬性(以什么順序)。

通過TypedArray,我們現(xiàn)在可以訪問各個屬性。我們需要使用R.styleable.ImageView_src,以便我們正確地索引數(shù)組中的屬性。

(回收類型數(shù)組也很重要,所以我把它放在上面的示例中。 .recycle(); )

通常您可以一次提取多個屬性。事實上,實際的ImageView實現(xiàn)比上面顯示的復(fù)雜得多(因為ImageView本身有更多的屬性關(guān)注)。

傳送門:官方文檔

Theme Attributes

我們不僅可以通過obtainStyledAttributes() 獲取屬性集 ,屬性集也可以存在于主題中。

這個真的用的很少,因為您的主題不應(yīng)該像src那樣設(shè)置屬性,但是如果您使用getsStyledAttributes()來檢索主題屬性(這是有用的,但不屬于本文的范圍),則可以發(fā)揮作用。

Default Style Attribute

你可能已經(jīng)注意到我在getsStyledAttributes()中為最后兩個參數(shù)使用了0。它們實際上是兩個資源引用 - defStyleAttr和defStyleRes。我將重點關(guān)注第一個。

到目前為止,defStyleAttr是getsStyledAttributes()最令人困惑的參數(shù)。根據(jù)文件說明:

當(dāng)前主題中的一個屬性,其中包含對為TypedArray提供默認(rèn)值的樣式資源的引用。

例如,如果要一次修改所有應(yīng)用程序的TextView,您可以在主題中設(shè)置textViewStyle。如果不存在,那么您必須手動為每個TextView設(shè)置樣式。

讓我們來看看它的實際工作原理,以TextView為例。

首先,它是一個屬性(在這種情況下為R.attr.textViewStyle)。這里是Android平臺定義textViewStyle的地方:


再次,我們使用declare-styleable,但這次定義可以存在于主題中的屬性。在這里,我們說textViewStyle是一個引用 - 也就是說,它的值只是一個對資源的引用。在這種情況下,它應(yīng)該是一種風(fēng)格的參考。

接下來我們必須在當(dāng)前主題中設(shè)置textViewStyle。默認(rèn)的Android主題看起來像這樣


然后,您的應(yīng)用程序或活動必須為主題設(shè)置,通常通過清單:

現(xiàn)在我們可以在getsStyledAttributes()中使用它:

最終結(jié)果是沒有由AttributeSet定義的任何屬性都使用textViewStyle引用的樣式來填充。

??!除非你是核心人物,否則你不需要知道所有這些實現(xiàn)細(xì)節(jié)。它主要在那里,以便Android框架可以讓您為主題中的各種視圖定義基本樣式。

Default Style Resource

defStyleRes比其兄弟姐妹更簡單。它只是一種風(fēng)格資源(即@ style / Widget.TextView)。沒有復(fù)雜的間接通過主題。defStyleRes中樣式的屬性僅在defStyleAttr未定義(0或未在主題中設(shè)置)時應(yīng)用。

Precedence

現(xiàn)在我們已經(jīng)有了很多方法來通過getsStyledAttributes()來獲取屬性的值。這是他們的優(yōu)先順序,從最高到最低:

1.AttributeSet中定義的任何值

2.AttributeSet中定義的樣式資源(即style = @ style / blah)。

3.由defStyleAttr指定的默認(rèn)樣式屬性。

4.由defStyleResource指定的默認(rèn)樣式資源(如果沒有defStyleAttr)。

5.定義在theme

換句話說,您首先使用直接在XML中設(shè)置的任何屬性。但是,如果您沒有設(shè)置自己的屬性,那么可以從中檢索出各種各樣的屬性

View constructors

這篇文章應(yīng)該是關(guān)于View構(gòu)造函數(shù)的,對吧? 共有四個,每個添加一個參數(shù):

一個重要的注意事項:最后一個被添加到API 21中,所以除非你有minSdkVersion 21,你應(yīng)該現(xiàn)在避免(如果你想使用defStyleRes,只要自己調(diào)用getsStyledAttributes(),因為它始終被支持。)

我通常設(shè)置我的自定義視圖,如下所示

無論如何,我希望這不僅有助于您對View構(gòu)造函數(shù)的理解,還有助于View視圖中檢索屬性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容