Carson帶你學(xué)Android:自定義View基礎(chǔ)必知必會(huì)!

前言

  • 自定義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)系

兩者坐標(biāo)系的區(qū)別

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();

具體如下圖:

get() 和 getRaw() 的區(qū)別

8. 角度(angle)& 弧度(radian)

  • 自定義View實(shí)際上是將一些簡(jiǎn)單的形狀通過(guò)計(jì)算,從而組合到一起形成的效果。

這會(huì)涉及到畫(huà)布的相關(guān)操作(旋轉(zhuǎn))、正余弦函數(shù)計(jì)算等,即會(huì)涉及到角度(angle)與弧度(radian)的相關(guān)知識(shí)。

  • 角度和弧度都是描述角的一種度量單位,區(qū)別如下圖::
角度和弧度區(qū)別

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

屏幕坐標(biāo)系角度增大方向

注:在常見(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為例介紹顏色定義:

ARGB88888

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)烈推薦!
Markman

10. 總結(jié)


歡迎關(guān)注Carson_Ho的簡(jiǎn)書(shū)

不定期分享關(guān)于安卓開(kāi)發(fā)的干貨,追求短、平、快,但卻不缺深度。


請(qǐng)點(diǎn)贊!因?yàn)槟愕墓膭?lì)是我寫(xiě)作的最大動(dòng)力!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容