前言
- 自定義View原理是Android開發者必須了解的基礎;
- 在了解自定義View之前,你需要有一定的知識儲備;
- 本文將全面解析關于自定義View中的所有知識基礎。
Carson帶你學Android自定義View文章系列:
Carson帶你學Android:自定義View基礎
Carson帶你學Android:一文梳理自定義View工作流程
Carson帶你學Android:自定義View繪制準備-DecorView創建
Carson帶你學Android:自定義View Measure過程
Carson帶你學Android:自定義View Layout過程
Carson帶你學Android:自定義View Draw過程
Carson帶你學Android:手把手教你寫一個完整的自定義View
Carson帶你學Android:Canvas類全面解析
Carson帶你學Android:Path類全面解析
目錄
1. 視圖定義
即日常說的View,具體表現為顯示在屏幕上的各種視圖控件,如TextView、LinearLayout等。
2. 視圖分類
視圖View主要分為兩類:
- 單一視圖:即一個View、不包含子View,如TextView
- 視圖組,即多個View組成的ViewGroup、包含子View,如LinearLayout
Android中的UI組件都由View、ViewGroup共同組成。
3. 視圖類簡介
- 視圖的核心類是:View類
- View類是Android中各種組件的基類,如View是ViewGroup基類
- View的構造函數:共有4個,具體如下:
自定義View必須重寫至少一個構造函數:
// 構造函數1
// 調用場景:View是在Java代碼里面new的
public CarsonView(Context context) {
super(context);
}
// 構造函數2
// 調用場景:View是在.xml里聲明的
// 自定義屬性是從AttributeSet參數傳進來的
public CarsonView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 構造函數3
// 應用場景:View有style屬性時
// 一般是在第二個構造函數里主動調用;不會自動調用
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 構造函數4
// 應用場景:View有style屬性時、API21之后才使用
// 一般是在第二個構造函數里主動調用;不會自動調用
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
更加具體的使用請看:深入理解View的構造函數和
理解View的構造函數
4. 視圖結構
- 對于包含子View的視圖組(ViewGroup),結構是樹形結構
- ViewGroup下可能有多個ViewGroup或View,如下圖:
這里需要特別注意的是:在View的繪制過程中,永遠都是從View樹結構的根節點開始(即從樹的頂端開始),一層一層、一個個分支地自上而下遍歷進行(即樹形遞歸),最終計算整個View樹中各個View,從而最終確定整個View樹的相關屬性。
5. Android坐標系
Android的坐標系定義為:
- 屏幕的左上角為坐標原點
- 向右為x軸增大方向
- 向下為y軸增大方向
具體如下圖:
注:區別于一般的數學坐標系
6. View位置(坐標)描述
視圖的位置由四個頂點決定,如圖1-3所示的A、B、C、D。
視圖的位置是相對于父控件而言的,四個頂點的位置描述分別由四個與父控件相關的值決定:
- 頂部(Top):視圖上邊界到父控件上邊界的距離;
- 左邊(Left):視圖左邊界到父控件左邊界的距離;
- 右邊(Right):視圖右邊界到父控件左邊界的距離;
- 底部(Bottom):視圖下邊界到父控件上邊界的距離。
具體如圖1-4所示。
可根據視圖位置的左上頂點、右下頂點進行記憶:
- 頂部(Top):視圖左上頂點到父控件上邊界的距離;
- 左邊(Left):視圖左上頂點到父控件左邊界的距離;
- 右邊(Right):視圖右下頂點到父控件左邊界的距離;
- 底部(Bottom):視圖右下頂點到父控件上邊界的距離。
7. 位置獲取方式
視圖的位置獲取是通過View.getXXX()
方法進行獲取。
獲取頂部距離(Top):getTop()
獲取左邊距離(Left):getLeft()
獲取右邊距離(Right):getRight()
獲取底部距離(Bottom):getBottom()
- 與MotionEvent中
get()
和getRaw()
的區別
//get() :觸摸點相對于其所在組件坐標系的坐標
event.getX();
event.getY();
//getRaw() :觸摸點相對于屏幕默認坐標系的坐標
event.getRawX();
event.getRawY();
具體如下圖:
8. 角度(angle)& 弧度(radian)
- 自定義View實際上是將一些簡單的形狀通過計算,從而組合到一起形成的效果。
這會涉及到畫布的相關操作(旋轉)、正余弦函數計算等,即會涉及到角度(angle)與弧度(radian)的相關知識。
- 角度和弧度都是描述角的一種度量單位,區別如下圖::
在默認的屏幕坐標系中角度增大方向為順時針。
注:在常見的數學坐標系中角度增大方向為逆時針
9. 顏色相關
Android中的顏色相關內容包括顏色模式,創建顏色的方式,以及顏色的混合模式等。
9.1 顏色模式
Android支持的顏色模式主要包括:
- ARGB8888:四通道高精度(32位)
- ARGB4444:四通道低精度(16位)
- RGB565:Android屏幕默認模式(16位)
- Alpha8:僅有透明通道(8位)
這里需要特別注意的是:
- 字母:表示通道類型;
- 數值:表示該類型用多少位二進制來描述;
- 示例說明:ARGB8888,表示有四個通道(ARGB);每個對應的通道均用8位來描述。
以ARGB8888為例介紹顏色定義:
9.2 顏色定義
主要分為xml定義 / java定義。
/**
* 定義方式1:xml
* 在/res/values/color.xml文件中定義
*/
<?xml version="1.0" encoding="utf-8"?>
<resources>
//定義了紅色(沒有alpha(透明)通道)
<color name="red">#ff0000</color>
//定義了藍色(沒有alpha(透明)通道)
<color name="green">#00ff00</color>
</resources>
// 在xml文件中以”#“開頭定義顏色,后面跟十六進制的值,有如下幾種定義方式:
#f00 //低精度 - 不帶透明通道紅色
#af00 //低精度 - 帶透明通道紅色
#ff0000 //高精度 - 不帶透明通道紅色
#aaff0000 //高精度 - 帶透明通道紅色
/**
* 定義方式2:Java
*/
// 使用Color類定義顏色
int color = Color.GRAY; //灰色
// Color類使用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文件中創建并使用顏色
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值定義的,而我們一般是無法直觀的知道自己需要顏色的值,需要借用取色工具直接從圖片或者其他地方獲取顏色的RGB值。
- 有時候一些簡單的顏色選取就不用去麻煩UI了,開發者自己去選取效率更高
- 這里,取色工具我強推Markman:一款設計師用于標注的工具,主要用于尺寸標注、字體大小標注、顏色標注,而且使用簡單。本人強烈推薦!
10. 總結
- 關于自定義View基礎已經講解完畢
- Carson帶你學Android自定義View文章系列:
Carson帶你學Android:自定義View基礎
Carson帶你學Android:一文梳理自定義View工作流程
Carson帶你學Android:自定義View繪制準備-DecorView創建
Carson帶你學Android:自定義View Measure過程
Carson帶你學Android:自定義View Layout過程
Carson帶你學Android:自定義View Draw過程
Carson帶你學Android:手把手教你寫一個完整的自定義View
Carson帶你學Android:Canvas類全面解析
Carson帶你學Android:Path類全面解析
歡迎關注Carson_Ho的簡書
不定期分享關于安卓開發的干貨,追求短、平、快,但卻不缺深度。