寫過自定義 View 的都知道,View 有四個構造函數,通常你們都知道第一個構造方法是簡單的在代碼中new
View 的時候調用的,第二個構造方法使用最普遍,是對應的生成 xml
中定義的 View 的時候調用的。剩下的兩個構造方法,你們瞭解的就比較少了。通常在自定義 View 的時候都會不加思索的按照固定的寫法。android
那麼你有沒有想探究一下里面的關係呢?函數
最簡單的構造方法,當在代碼中建立一個 View 的時候使用。這種構造方法咱們通常不會使用。通常都是在 xml 中定義 view ,不多有直接進行 new view 的,這樣寫法也不符合規範!佈局
這個構造方法是咱們最經常使用的,當咱們在 xml 中定義了 View 而後在代碼中使用這個 View 的時候,這個 View 就是利用這個構造方法生成的。View 的屬性值來自 AttributeSet 的值。字體
這個構造方法就是提供了默認的 defStyleAttr
用於指定基本的屬性。也就是容許 View 有本身基礎的風格。例如:一個 Button 類在調用這個構造函數的時候會給 defStyleAttr
賦予一個默認的值 R.attr.buttonStyle
這個值包含了 Button 的一些基本的風格(會在 Theme 中給出),好比:最小寬度,最大寬度等等基礎風格。固然這些值咱們均可以在 xml
中經過屬性直接改變。code
這個構造方法對比構造方法三就多了一個參數 defStyleRes
這個參數的做用就是再提供一個給 View 提供默認屬性的手段。defStyleRes
就是把一些咱們想要的屬性寫到一個 Style 裏面,而後把這個 style 賦值給 defStyleRes
就能夠了。cdn
第一個構造函數:這個構造函數就是在代碼中直接 new view 的時候使用,這樣出來的 View 默認是沒有任何的屬性值,須要後面本身手動 set。xml
第二個構造函數:這個構造函數是在代碼中生成對應 xml
中定義的 View 使用的。這個時候在 xml
中定義的屬性值會經過 AttributeSet
傳遞,這樣生成的 View 對象是有默認的屬性值的。對象
第三個構造函數:這個構造函數就是相對於第二個構造函數,多提供了一種給 View 添加默認屬性的方式,經過 deftStyleAttr
若是沒有默認的值,就用 0 。這樣作的好處就是,咱們能夠默認一個 View 的基礎風格。好比能夠在 defSyleAttr
中設置背景顏色,字體大小等等基礎風格,這樣咱們定義的這個 View 就有了原始風格了,固然若是你在 xml
中又設置了背景顏色,等於改變了原始的風格,是最優先於 xml
中的屬性的。blog
其實咱們使用的不少系統 View 都是經過這種方式來,這裏用 Button
來舉個例子get
能夠看到 Button 在使用第三個構造函數的時候,傳入了 com.android.internal.R.attr.buttonSyle
這個屬性,這個屬性咱們在屬性定義文件 attr
中找到,這個屬性的出現就是用來定義 Button 的默認風格的。
而後在主題中給 buttonStyle
賦值,找到系統 Theme
能夠看到在系統的 Theme 中給 buttonSyle
賦值了,指向了 style/Widget.Holo.Light.Button
這個風格就指定了 Button 的默認風格,固然咱們在定義主題的時候,能夠本身定義 buttonStyle
這個屬性的值。
看一下 style/Widget.Holo.Light.Button
的內容
這裏定義了 Button 的一些默認的樣式。
其餘的 View 也都同樣,都是這樣的一個路子。
第四個構造函數:第四個構造函數相對第三個構造函數就多了一個 defStyleRes
,說白了就是多了一種提供 View 默認屬性的一種方式。這種方式更加的簡單,直接在代碼中傳入 R.style.XX
就能夠了。若是沒有默認值的話就爲 0 。這個參數只有 defStyleAttr
爲 0 的時候纔會生效。
咱們在 xml
佈局文件中,定義 View 的時候,會設定這個 View 不少的屬性。AttributeSet 就能夠看作是這些屬性的集合,包含了屬性名和屬性值。
舉例說明:
第一步:定義 CustomTextView
能夠看到,我在第二個構造函數中把 AttributeSet 的 name 和 value 都打印出來了。
第二步:xml 中使用 CustomTextView
第三步:運行程序,查看結果
能夠看到 xml 中定義的 5 個屬性所有打印出來。所以 AttributeSet 對應的就是 xml 佈局文件中定義的屬性
直接經過 xml 中的屬性
這種方式是最直接的,體現形式就是直接在佈局中設置屬性,在 xml 佈局文件中使用 style 也屬於這種方式
經過 deftStyleAttr
設置屬性
這種方式主要是用來設置默認屬性風格的,使用方式見上面 button,主題中設置不一樣的類型,View的默認風格會發生改變。
經過 defStyleRes
設置屬性
這種方式是直接在代碼中指定一個默認的 style,和 Context 的主題沒有關係
在 Theme 中設置屬性
這種方式很是不常見,就是把在佈局文件中設置的屬性,直接放到 Them 中。
若是同時使用這幾種方式給 View 設置了屬性那麼 View 聽誰的呢?
xml中直接定義 > xml 中 style 定義 >defStyleAttr > defStyleRes > Theme 中直接定義
文字關注: