本章目錄
- Part One:自定義View概述
- Part Two:構(gòu)造方法
- Part Three:構(gòu)造方法的寫法
Part One:自定義View概述
自定義View可以說是Android里最易學難精的知識點之一,它的入門非常的簡單,實現(xiàn)幾個固定方法即可,幾十行代碼就可以畫出一個簡單的圖形。
但是,要想打包票說自己精通自定義View,是非常非常難以做到的事情,因為這里面不僅僅需要處理各種復雜的邏輯,還會涉及到大量的數(shù)學算法。
老實說,我也在學習的路上,這里只是給大家拋磚引玉一下。
好了,閑話不多說,自定義View大致上有以下三種應用情況:
- 在現(xiàn)有的控件上,做些個性化的處理(繼承自ImageView等 )
- 現(xiàn)有的控件不滿足于我們的需求,需要自己去創(chuàng)造(繼承自View)
- 講幾個控件組合到一起,新生成一個(繼承自ViewGroup)
而繼承自現(xiàn)有控件和繼承自View的應用方式差不太多,我們用一個畫圓的案例把這兩種情況需要掌握的各個知識點引入。
Part Two:構(gòu)造方法
新建一個CircleView類,繼承自View,提示需要添加構(gòu)造方法,如下圖所示:
其中,四個參數(shù)的構(gòu)造方法是Android5.0以后引入的,所以最低需要SDK21。
當然,這四個構(gòu)造方法并不需要全部創(chuàng)建出來,大部分情況下,我們只要掌握前兩個即可,我們一一來看下它們的應用場景。
- 首先是一個參數(shù)的構(gòu)造方法。
SingleParameterConstructor.png
它的應用范圍比較小,沒有涉及到屬性的添加,不能在XML布局文件中使用。在代碼中直接new一個自定義View實例的時候,才會調(diào)用此構(gòu)造方法。例如:
SingleParameterConstructorUsage.png
其中,參數(shù)傳入一個context對象即可生成一個實例,類似于我們直接new一個TextView(this);這種方式。 -
接下來我們看2個參數(shù)的構(gòu)造方法。
TwoParameterConstructor.png
這種方法適用于我們常用的控件使用方法,即在XML布局文件中調(diào)用自定義View的時候,會使用此構(gòu)造方法,例如:
TwoParameterConstructorUsage.png
高度和寬度是在XML文件中必須寫的內(nèi)容,還有路徑要寫全,包括包名和類名。完成這兩步就可以在代碼中實例化該控件了。 - 然后是3個參數(shù)的構(gòu)造方法
ThreParameterConstructor.png
這里要非常的注意,在xml布局文件中調(diào)用自定義View,并且自定義View標簽中還有自定義屬性時,這里調(diào)用的還是第二個構(gòu)造函數(shù)。
因為系統(tǒng)只會默認調(diào)用前兩個構(gòu)造方法,而如果我們想使用自定義屬性,或者說后兩個構(gòu)造方法,必須在前面兩個構(gòu)造方法里手動調(diào)用(例如:在第二個構(gòu)造方法里用this關(guān)鍵字調(diào)用此構(gòu)造方法)。 -
最后是4個參數(shù)的構(gòu)造方法
FourParameterConstructor.png
應用方式和三個參數(shù)的構(gòu)造方法一樣,都是手動調(diào)用。
至于四個參數(shù)分別是什么,這里先大概說一下,下一篇文章會詳細解釋
- context:The Context the view is running in, through which it can access the current theme, resources, etc. 也就是上下文對象
- attrs:The attributes of the XML tag that is inflating the view. 一些基礎(chǔ)的XML布局使用的屬性值集合。
- defStyleAttr:An attribute in the current theme that contains a reference to a style resource that supplies default values for the view. Can be 0 to not look for defaults. 就是theme中包含一個指向style資源的引用。當我們沒有給自定義View設(shè)置屬性時,就會調(diào)用這些默認的值,如果傳入0表示不調(diào)用該默認值。
- defStyleRes:A resource identifier of a style resource that supplies default values for the view, used only if defStyleAttr is 0 or can not be found in the theme. Can be 0 to not look for defaults. 它的性質(zhì)和defStyleAttr差不多,但是只有defStyleAttr設(shè)置為0或者在當前的theme中沒有找到相關(guān)屬性時,才會去讀取該屬性,那么很明顯優(yōu)先級是defStyleAttr更高。
Part Three:構(gòu)造方法的寫法
我們常用的構(gòu)造方法的寫法有兩種
-
第一種,使用this關(guān)鍵字方式,逐級調(diào)用,最終調(diào)用四個參數(shù)的構(gòu)造方法:
FirstConstructor.png
它的使用方式和官方的控件的構(gòu)造方法是一樣的,我們可以看看官方Button是怎么設(shè)計的。
Button.png
這里官方填寫了defStyleAttr這個參數(shù),所以說一般我們繼承自View,想要傳入?yún)?shù)的時候,使用這種構(gòu)造方法即可。
但是,如果如果繼承自已有的控件,比如Button時,這種構(gòu)造方法的寫法會覆蓋掉父類一些默認設(shè)置的style。此時,我們最好使用第二種寫法。 -
第二種,把初始化的內(nèi)容封裝到一個方法里,給各個構(gòu)造方法調(diào)用:
SecondConstructor.png
當然了,并不是說我們必須使用第二種方式去處理繼承自已有控件的狀況。這么做只是因為可以節(jié)省一些工作量,畢竟我們只是在原有的基礎(chǔ)上,做一些微調(diào)。
官方的控件處理這種狀況,依然是使用第一種方式,比如EditText就是繼承自TextView,官方把defStyleAttr重新定義了一遍。這里我看不到源碼,猜測這兩個style有很大概率是有一些繼承關(guān)系在里面的。相對來說,工作量比較大,改動也比較大。
而如果不需要defStyleAttr時,這兩種寫法是沒有區(qū)別的,任意選用即可。
暫時先寫到這,下一節(jié)會繼續(xù)寫寫自定義View的onDraw方法和自定義屬性。