1. 程式人生 > >從 View 的四個構造方法說起

從 View 的四個構造方法說起

View 類的四個建構函式

寫過自定義 View 的都知道,View 有四個建構函式,一般大家都知道第一個構造方法是簡單的在程式碼中new View 的時候呼叫的,第二個構造方法使用最廣泛,是對應的生成 xml 中定義的 View 的時候呼叫的。剩下的兩個構造方法,大家瞭解的就比較少了。一般在自定義 View 的時候都會不加思索的按照固定的寫法。

那麼你有沒有想探究一下里面的關係呢?

構造方法 View(Context context)

最簡單的構造方法,當在程式碼中建立一個 View 的時候使用。這種構造方法我們一般不會使用。一般都是在 xml 中定義 view ,很少有直接進行 new view 的,這樣寫法也不符合規範!

構造方法 View(Context context,@Nullable AttributeSet attrs)

這個構造方法是我們最常用的,當我們在 xml 中定義了 View 然後在程式碼中使用這個 View 的時候,這個 View 就是利用這個構造方法生成的。View 的屬性值來自 AttributeSet 的值。

構造方法 View(Context context,@Nullable AttributeSet attrs,int defStyleAttr)

這個構造方法就是提供了預設的 defStyleAttr 用於指定基本的屬性。也就是允許 View 有自己基礎的風格。例如:一個 Button 類在呼叫這個建構函式的時候會給 defStyleAttr

賦予一個預設的值 R.attr.buttonStyle 這個值包含了 Button 的一些基本的風格(會在 Theme 中給出),比如:最小寬度,最大寬度等等基礎風格。當然這些值我們都可以在 xml 中通過屬性直接改變。

構造方法 View(Context context ,@Nullable AttributeSet attrs,int defStyleAttr,int defStyleRes)

這個構造方法對比構造方法三就多了一個引數 defStyleRes 這個引數的作用就是再提供一個給 View 提供預設屬性的手段。defStyleRes 就是把一些我們想要的屬性寫到一個 Style 裡面,然後把這個 style 賦值給 defStyleRes

就可以了。

四個建構函式總結

第一個建構函式:這個建構函式就是在程式碼中直接 new view 的時候使用,這樣出來的 View 預設是沒有任何的屬性值,需要後面自己手動 set。

第二個建構函式:這個建構函式是在程式碼中生成對應 xml 中定義的 View 使用的。這個時候在 xml 中定義的屬性值會通過 AttributeSet 傳遞,這樣生成的 View 物件是有預設的屬性值的。

第三個建構函式:這個建構函式就是相對於第二個建構函式,多提供了一種給 View 新增預設屬性的方式,通過 deftStyleAttr 如果沒有預設的值,就用 0 。這樣做的好處就是,我們可以預設一個 View 的基礎風格。比如可以在 defSyleAttr 中設定背景顏色,字型大小等等基礎風格,這樣我們定義的這個 View 就有了原始風格了,當然如果你在 xml 中又設定了背景顏色,等於改變了原始的風格,是最優先於 xml 中的屬性的。

其實我們使用的很多系統 View 都是通過這種方式來,這裡用 Button 來舉個例子

可以看到 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 的時候才會生效。

關於 AttributeSet

我們在 xml 佈局檔案中,定義 View 的時候,會設定這個 View 很多的屬性。AttributeSet 就可以看做是這些屬性的集合,包含了屬性名和屬性值。

舉例說明:

第一步:定義 CustomTextView

可以看到,我在第二個建構函式中把 AttributeSet 的 name 和 value 都打印出來了。

第二步:xml 中使用 CustomTextView

第三步:執行程式,檢視結果

可以看到 xml 中定義的 5 個屬性全部打印出來。因此 AttributeSet 對應的就是 xml 佈局檔案中定義的屬性

給 View 提供樣式的方式

  • 直接通過 xml 中的屬性

    這種方式是最直接的,體現形式就是直接在佈局中設定屬性,在 xml 佈局檔案中使用 style 也屬於這種方式

  • 通過 deftStyleAttr 設定屬性

    這種方式主要是用來設定預設屬性風格的,使用方式見上面 button,主題中設定不同的型別,View的預設風格會發生改變。

  • 通過 defStyleRes 設定屬性

    這種方式是直接在程式碼中指定一個預設的 style,和 Context 的主題沒有關係

  • 在 Theme 中設定屬性

    這種方式非常不常見,就是把在佈局檔案中設定的屬性,直接放到 Them 中。

如果同時使用這幾種方式給 View 設定了屬性那麼 View 聽誰的呢?

xml中直接定義 > xml 中 style 定義 >defStyleAttr > defStyleRes > Theme 中直接定義

相關推薦

View構造方法

View 類的四個建構函式 寫過自定義 View 的都知道,View 有四個建構函式,一般大家都知道第一個構造方法是簡單的在程式碼中new View 的時候呼叫的,第二個構造方法使用最廣泛,是對應的生成 xml 中定義的 View 的時候呼叫的。剩下的兩個構造方法,大家瞭解的就比較少了。一般在自定義

徹底搞懂自定義控制元件中的構造方法

    在上一篇部落格動手實現餅圖控制元件寫完以後,有些小夥伴說講得不夠細,建議從最基本開始講起,比如建構函式都是什麼?我覺得說得很有道理,正好自己也不夠了解自定義控制元件中的4個構造方法的具體呼叫時機和它們各自的引數作用,今天終於有時間把這部分內容進行學習整理,順便分享給那

android View的三構造方法 簡單總結

在android開發中,我們經常會涉及到自定義View,View有3個構造方法(可能以後會更多),如下: public CircleView(Context context) { this(context,null); }public CircleView(Contex

ps--提升字體排版的美感有效方法

提升 技術分享 img 超過 註意 http 文字 mage 圖片 一,文字的擺放位置 (字體的選擇不要超過三種,分散註意力) ps--提升字體排版的美感四個有效方法

程式設計師提高自己的英語水平,可以以下方面著手

  對於程式設計師來說,英語儼然成為自己必備語言。因為計算機起源和發展都源於英語世界,準確和權威的資料都是英文原版。翻譯帶來的誤解和差異很多時候會成為我們學習的困擾。   不僅僅是閱讀障礙需要提升自己的英語水平,在自己編寫程式碼的時候英語也是非常重要的。因為目前流行的程式語言都是貼近

jedis set 的過載方法

方法定義如下: 1、String set(String key, String value) 2、String set(String key, String value, String nxxx) 3、String set(String key, String value, Str

(1).Person類有name,age,salary屬性,要求實現至少兩構造方法,並且屬性私有,提供對應的getter、setter。 2).覆寫toString方法,要求在System.out.

/** (1).Person類有name,age,salary屬性,要求實現至少兩個構造方法,並且屬性私有,提供對應的getter、setter。2).覆寫toString方法,要求在System.out.println()函式中傳遞Person物件能打印出三個屬性值而不是物

多執行緒同步互斥的實現方法

一、引言 這篇文章記錄是來源於Windows多執行緒系列的學習筆記,表為原創,實為轉載文章,只是為了讓自己學的明白,稍微整理了下而已,在此向“MoreWindows”大神致敬! 二、關鍵段與互斥量Mutex 名稱 建立或初始化 銷燬

HashMap的幾構造方法解析

HashMap的幾個構造方法原始碼解析(基於JDK1.8中的HashMap原始碼) 1、無參構造方法HashMap() /** * Constructs an empty <tt>HashMap</tt> with the default initial capac

java中一個類中能如何宣告多構造方法

                public class A{public A(){}  //構造1public A(i

python魔法方法__len__,__getitem__,__setitem__,__delitem__

python中除了可以使用內建的型別,如list,tuple,dict,還可以建立自己的物件來實現像這些內建型別的訪問,不過需要在定義類的時候對一些魔法方法逐一實現。 如下: class DictDemo: def __init__(self,key,valu

eclipse中如何為類快速新增多構造方法

今天,看視訊裡一下子加了3個構造方法,驚奇了,仔細看了一下。 選中報錯類名,按快捷鍵:alt+shift+s,會出現下圖: 選中劃橫線的部分,會出現下面j介面: eclipse會預設“select

i2c裝置驅動的構造方法

i2c裝置驅動屬於字元裝置驅動,其構造自然是跟字元裝置的結構一樣了,字元裝置:1、 分配字元裝置號(主次裝置號),設定為0,表示自動分配裝置號  2、構造file_operatios 3、註冊裝置,register_chrdev(1,2,3),三個引數分別是裝置號,名稱(不

兔子繁殖問題,設有一對新生兔子,月開始他們每個月月初都生一對兔子 新生的兔子月月初開始又每個月生一對兔子 按此規律,並假定兔子沒有死亡,n(n

兔子繁殖問題,設有一對新生兔子,從第四個月開始他們每個月月初都生一對兔子 新生的兔子從第四個月月初開始又每個月生一對兔子 按此規律,並假定兔子沒有死亡,n(n <= 20)個月月末共有多少對兔子

有一頭母牛,它每年年初生一頭小母牛。每頭小母牛年頭開始,每年年初也生一頭小母牛。請程式設計實現在第n年的時候,共有多少頭母牛?

要知道今年的小牛數量,即為去年的小牛數量加上今年出生的小牛數量(即為四年前的小牛數量)。找到這個規律即可編寫相應程式碼。#include<stdio.h>int main(void){int n;int x[56]={0,1,2,3,4};int i;for(i=

把註冊流程頁面做到三是什麼體驗?

你沒有看錯,我的標題也沒有寫錯,一個APP的註冊流程可以長達14個頁面。14個頁面的註冊流程,對於APP推廣來說,簡直就是一場災難。如果你對APP的各個頁面進行了埋點,那麼一定能夠發現,使用者隨著流程的一步步進行逐漸流失,最終能爬上註冊這座大山的寥寥無幾。 如下圖就是,就是14個頁面的註冊流程(只標示了頁面主

java--Fibonacc由數字1、1、2、3...組成的,第三數字每一個數字為前兩數字的和。建立一個方法,接受一個整數引數,顯示第一元素開始總共由該引數指定的個數所構成的所有斐波那契數

題目完整描述:一個斐波那契數列是由數字1、1、2、3、5、8、13、21、34等等組成的,其中每一個數字(從第三個數字起)都是前兩個數字的和。建立一個方法,接受一個整數引數,並顯示從第一個元素開始總共由該引數指定的個數所構成的所有斐波那契數字。例如,如果執行 java Fibonacci 5(Fib

第一爬蟲建立做蟲師的心,request物件,簡單使用,構造簡單的裝置請求頭,爬蟲簡單案例篇(2)

from urllib.request import urlopen from urllib.request import Request url ='http://www.baidu.com/' h

若一頭小母牛,出生年頭開始每年生一頭母牛,按此規律,第n年時有多少頭母牛?

第一年:1 第二年:1 第三年:1 第四年:1 + 1(4) 第五年:1 + 1(4) + 1(5) 第六年:1 + 1(4) + 1(5) + 1(6) 第七年:1 + 1(4) + 1(5) + 1(6) + 1(7) +1(47) 遞迴公式:f(n)=1 0

#Android原始碼#View構造方法為什麼要4

問題描述 在View中發現有四個構造方法(5.0下是三個),如下,有什麼玄妙嗎? //C1 public View(Context context) { .... } //C2 public View(Context context, @Null