
前言
- 自定義View原理是Android開(kāi)發(fā)者必須了解的基礎(chǔ);
- 在了解自定義View之前,你需要有一定的知識(shí)儲(chǔ)備;
- 本文將全面解析關(guān)于自定義View中的所有知識(shí)基礎(chǔ)。
Carson帶你學(xué)Android自定義View文章系列:
Carson帶你學(xué)Android:自定義View基礎(chǔ)
Carson帶你學(xué)Android:一文梳理自定義View工作流程
Carson帶你學(xué)Android:自定義View繪制準(zhǔn)備-DecorView創(chuàng)建
Carson帶你學(xué)Android:自定義View Measure過(guò)程
Carson帶你學(xué)Android:自定義View Layout過(guò)程
Carson帶你學(xué)Android:自定義View Draw過(guò)程
Carson帶你學(xué)Android:手把手教你寫(xiě)一個(gè)完整的自定義View
Carson帶你學(xué)Android:Canvas類(lèi)全面解析
Carson帶你學(xué)Android:Path類(lèi)全面解析
目錄

1. 視圖定義
即日常說(shuō)的View,具體表現(xiàn)為顯示在屏幕上的各種視圖控件,如TextView、LinearLayout等。
2. 視圖分類(lèi)
視圖View主要分為兩類(lèi):
- 單一視圖:即一個(gè)View、不包含子View,如TextView
- 視圖組,即多個(gè)View組成的ViewGroup、包含子View,如LinearLayout
Android中的UI組件都由View、ViewGroup共同組成。
3. 視圖類(lèi)簡(jiǎn)介
- 視圖的核心類(lèi)是:View類(lèi)
- View類(lèi)是Android中各種組件的基類(lèi),如View是ViewGroup基類(lèi)
- View的構(gòu)造函數(shù):共有4個(gè),具體如下:
自定義View必須重寫(xiě)至少一個(gè)構(gòu)造函數(shù):
// 構(gòu)造函數(shù)1
// 調(diào)用場(chǎng)景:View是在Java代碼里面new的
public CarsonView(Context context) {
super(context);
}
// 構(gòu)造函數(shù)2
// 調(diào)用場(chǎng)景:View是在.xml里聲明的
// 自定義屬性是從AttributeSet參數(shù)傳進(jìn)來(lái)的
public CarsonView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 構(gòu)造函數(shù)3
// 應(yīng)用場(chǎng)景:View有style屬性時(shí)
// 一般是在第二個(gè)構(gòu)造函數(shù)里主動(dòng)調(diào)用;不會(huì)自動(dòng)調(diào)用
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 構(gòu)造函數(shù)4
// 應(yīng)用場(chǎng)景:View有style屬性時(shí)、API21之后才使用
// 一般是在第二個(gè)構(gòu)造函數(shù)里主動(dòng)調(diào)用;不會(huì)自動(dòng)調(diào)用
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
更加具體的使用請(qǐng)看:深入理解View的構(gòu)造函數(shù)和
理解View的構(gòu)造函數(shù)
4. 視圖結(jié)構(gòu)
- 對(duì)于包含子View的視圖組(ViewGroup),結(jié)構(gòu)是樹(shù)形結(jié)構(gòu)
- ViewGroup下可能有多個(gè)ViewGroup或View,如下圖:

這里需要特別注意的是:在View的繪制過(guò)程中,永遠(yuǎn)都是從View樹(shù)結(jié)構(gòu)的根節(jié)點(diǎn)開(kāi)始(即從樹(shù)的頂端開(kāi)始),一層一層、一個(gè)個(gè)分支地自上而下遍歷進(jìn)行(即樹(shù)形遞歸),最終計(jì)算整個(gè)View樹(shù)中各個(gè)View,從而最終確定整個(gè)View樹(shù)的相關(guān)屬性。
5. Android坐標(biāo)系
Android的坐標(biāo)系定義為:
- 屏幕的左上角為坐標(biāo)原點(diǎn)
- 向右為x軸增大方向
- 向下為y軸增大方向
具體如下圖:

注:區(qū)別于一般的數(shù)學(xué)坐標(biāo)系

6. View位置(坐標(biāo))描述
視圖的位置由四個(gè)頂點(diǎn)決定,如圖1-3所示的A、B、C、D。

視圖的位置是相對(duì)于父控件而言的,四個(gè)頂點(diǎn)的位置描述分別由四個(gè)與父控件相關(guān)的值決定:
- 頂部(Top):視圖上邊界到父控件上邊界的距離;
- 左邊(Left):視圖左邊界到父控件左邊界的距離;
- 右邊(Right):視圖右邊界到父控件左邊界的距離;
- 底部(Bottom):視圖下邊界到父控件上邊界的距離。
具體如圖1-4所示。

可根據(jù)視圖位置的左上頂點(diǎn)、右下頂點(diǎn)進(jìn)行記憶:
- 頂部(Top):視圖左上頂點(diǎn)到父控件上邊界的距離;
- 左邊(Left):視圖左上頂點(diǎn)到父控件左邊界的距離;
- 右邊(Right):視圖右下頂點(diǎn)到父控件左邊界的距離;
- 底部(Bottom):視圖右下頂點(diǎn)到父控件上邊界的距離。
7. 位置獲取方式
視圖的位置獲取是通過(guò)View.getXXX()方法進(jìn)行獲取。
獲取頂部距離(Top):getTop()
獲取左邊距離(Left):getLeft()
獲取右邊距離(Right):getRight()
獲取底部距離(Bottom):getBottom()
- 與MotionEvent中
get()和getRaw()的區(qū)別
//get() :觸摸點(diǎn)相對(duì)于其所在組件坐標(biāo)系的坐標(biāo)
event.getX();
event.getY();
//getRaw() :觸摸點(diǎn)相對(duì)于屏幕默認(rèn)坐標(biāo)系的坐標(biāo)
event.getRawX();
event.getRawY();
具體如下圖:

8. 角度(angle)& 弧度(radian)
- 自定義View實(shí)際上是將一些簡(jiǎn)單的形狀通過(guò)計(jì)算,從而組合到一起形成的效果。
這會(huì)涉及到畫(huà)布的相關(guān)操作(旋轉(zhuǎn))、正余弦函數(shù)計(jì)算等,即會(huì)涉及到角度(angle)與弧度(radian)的相關(guān)知識(shí)。
- 角度和弧度都是描述角的一種度量單位,區(qū)別如下圖::

在默認(rèn)的屏幕坐標(biāo)系中角度增大方向?yàn)轫槙r(shí)針。

注:在常見(jiàn)的數(shù)學(xué)坐標(biāo)系中角度增大方向?yàn)槟鏁r(shí)針
9. 顏色相關(guān)
Android中的顏色相關(guān)內(nèi)容包括顏色模式,創(chuàng)建顏色的方式,以及顏色的混合模式等。
9.1 顏色模式
Android支持的顏色模式主要包括:
- ARGB8888:四通道高精度(32位)
- ARGB4444:四通道低精度(16位)
- RGB565:Android屏幕默認(rèn)模式(16位)
- Alpha8:僅有透明通道(8位)
這里需要特別注意的是:
- 字母:表示通道類(lèi)型;
- 數(shù)值:表示該類(lèi)型用多少位二進(jìn)制來(lái)描述;
- 示例說(shuō)明:ARGB8888,表示有四個(gè)通道(ARGB);每個(gè)對(duì)應(yīng)的通道均用8位來(lái)描述。
以ARGB8888為例介紹顏色定義:

9.2 顏色定義
主要分為xml定義 / java定義。
/**
* 定義方式1:xml
* 在/res/values/color.xml文件中定義
*/
<?xml version="1.0" encoding="utf-8"?>
<resources>
//定義了紅色(沒(méi)有alpha(透明)通道)
<color name="red">#ff0000</color>
//定義了藍(lán)色(沒(méi)有alpha(透明)通道)
<color name="green">#00ff00</color>
</resources>
// 在xml文件中以”#“開(kāi)頭定義顏色,后面跟十六進(jìn)制的值,有如下幾種定義方式:
#f00 //低精度 - 不帶透明通道紅色
#af00 //低精度 - 帶透明通道紅色
#ff0000 //高精度 - 不帶透明通道紅色
#aaff0000 //高精度 - 帶透明通道紅色
/**
* 定義方式2:Java
*/
// 使用Color類(lèi)定義顏色
int color = Color.GRAY; //灰色
// Color類(lèi)使用ARGB值表示
int color = Color.argb(127, 255, 0, 0); //半透明紅色
int color = 0xaaff0000; //帶有透明度的紅色
9.3 顏色引用
主要分為xml定義 / java定義。
/**
* 引用方式1:xml
*/
// 1. 在style文件中引用
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/red</item>
</style>
// 2. 在layout文件中引用
android:background="@color/red"
// 3. 在layout文件中創(chuàng)建并使用顏色
android:background="#ff0000"
/**
* 引用方式2:Java
*/
//方法1
int color = getResources().getColor(R.color.mycolor);
//方法2(API 23及以上)
int color = getColor(R.color.myColor);
9.4 取色工具
- 顏色都是用RGB值定義的,而我們一般是無(wú)法直觀(guān)的知道自己需要顏色的值,需要借用取色工具直接從圖片或者其他地方獲取顏色的RGB值。
- 有時(shí)候一些簡(jiǎn)單的顏色選取就不用去麻煩UI了,開(kāi)發(fā)者自己去選取效率更高
- 這里,取色工具我強(qiáng)推Markman:一款設(shè)計(jì)師用于標(biāo)注的工具,主要用于尺寸標(biāo)注、字體大小標(biāo)注、顏色標(biāo)注,而且使用簡(jiǎn)單。本人強(qiáng)烈推薦!

10. 總結(jié)
- 關(guān)于自定義View基礎(chǔ)已經(jīng)講解完畢
- Carson帶你學(xué)Android自定義View文章系列:
Carson帶你學(xué)Android:自定義View基礎(chǔ)
Carson帶你學(xué)Android:一文梳理自定義View工作流程
Carson帶你學(xué)Android:自定義View繪制準(zhǔn)備-DecorView創(chuàng)建
Carson帶你學(xué)Android:自定義View Measure過(guò)程
Carson帶你學(xué)Android:自定義View Layout過(guò)程
Carson帶你學(xué)Android:自定義View Draw過(guò)程
Carson帶你學(xué)Android:手把手教你寫(xiě)一個(gè)完整的自定義View
Carson帶你學(xué)Android:Canvas類(lèi)全面解析
Carson帶你學(xué)Android:Path類(lèi)全面解析
歡迎關(guān)注Carson_Ho的簡(jiǎn)書(shū)
不定期分享關(guān)于安卓開(kāi)發(fā)的干貨,追求短、平、快,但卻不缺深度。
