前言
- 自定義View原理是Android開發(fā)者必須了解的基礎;
- 在了解自定義View之前悬秉,你需要有一定的知識儲備;
- 本文將全面解析關(guān)于自定義View中的所有知識基礎。
目錄
image.png
View的分類
視圖View主要分為兩類:
班級 | 解釋 | 特點 |
---|---|---|
單一視圖 | 即一個View劲妙,如TextView | 不包含子View |
視圖組 | 即多個View組成的ViewGroup,如LinearLayout | 包含子View |
View類簡介
View類是Android中各種組件的基類儒喊,如View是ViewGroup基類
View表現(xiàn)為顯示在屏幕上的各種視圖
Android中的UI組件都由View镣奋、ViewGroup組成。
View的構(gòu)造函數(shù):共有4個怀愧,具體如下:
// 如果View是在Java代碼里面new的侨颈,則調(diào)用第一個構(gòu)造函數(shù)
public CarsonView(Context context) {
super(context);
}
// 如果View是在.xml里聲明的余赢,則調(diào)用第二個構(gòu)造函數(shù)
// 自定義屬性是從AttributeSet參數(shù)傳進來的
public CarsonView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 不會自動調(diào)用
// 一般是在第二個構(gòu)造函數(shù)里主動調(diào)用
// 如View有style屬性時
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//API21之后才使用
// 不會自動調(diào)用
// 一般是在第二個構(gòu)造函數(shù)里主動調(diào)用
// 如View有style屬性時
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
一般自定義view的時候會這樣重寫三個構(gòu)造函數(shù)
public CircleProgressView(Context context) {
this(context, null);
}
public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
location = array.getInt(R.styleable.CircleProgressView_location, 1);
mPaintWidth = array.getDimension(R.styleable.CircleProgressView_progress_paint_width, dip2px(context, 4));//默認4dp
mPaintColor = array.getColor(R.styleable.CircleProgressView_progress_paint_color, mPaintColor);
mTextSize = array.getDimension(R.styleable.CircleProgressView_progress_text_size, dip2px(context, 18));//默認18sp
mTextColor = array.getColor(R.styleable.CircleProgressView_progress_text_color, mTextColor);
array.recycle();
}
View視圖結(jié)構(gòu)
image.png
記住:無論是measure過程哈垢、layout過程還是draw過程妻柒,永遠都是從View樹的根節(jié)點開始測量或計算(即從樹的頂端開始),一層一層温赔、一個分支一個分支地進行(即樹形遞歸)蛤奢,最終計算整個View樹中各個View,最終確定整個View樹的相關(guān)屬性陶贼。
Android坐標系
Android的坐標系定義為:
- 屏幕的左上角為坐標原點
- 向右為x軸增大方向
- 向下為y軸增大方向
-
具體如下圖:
注:區(qū)別于一般的數(shù)學坐標系
View位置(坐標)描述
-
View的位置由4個頂點決定的(如下A啤贩、B、C拜秧、D)
4個頂點的位置描述分別由4個值決定:
(請記妆砸佟:View的位置是相對于父控件而言的)
Top:子View上邊界到父view上邊界的距離
Left:子View左邊界到父view左邊界的距離
Bottom:子View下邊距到父View上邊界的距離
Right:子View右邊界到父view左邊界的距離
如下圖:
按頂點位置來記憶:
Top:子View左上角距父View頂部的距離;
Left:子View左上角距父View左側(cè)的距離枉氮;
Bottom:子View右下角距父View頂部的距離
Right:子View右下角距父View左側(cè)的距離
位置獲取方式
View的位置是通過view.getxxx()函數(shù)進行獲戎狙堋:(以Top為例)
// 獲取Top位置
public final int getTop() {
return mTop;
}
// 其余如下:
getLeft(); //獲取子View左上角距父View左側(cè)的距離
getBottom(); //獲取子View右下角距父View頂部的距離
getRight(); //獲取子View右下角距父View左側(cè)的距離123456789
- 與MotionEvent中 get()和getRaw()的區(qū)別
//get() :觸摸點相對于其所在組件坐標系的坐標
event.getX();
event.getY();
//getRaw() :觸摸點相對于屏幕默認坐標系的坐標
event.getRawX();
event.getRawY();
具體如下圖: