
其中onLayout()函數(shù)只有在自定義ViewGroup的時候才會用到
分類
自定義View分為兩類:
自定義ViewGroup
自定義ViewGroup一般就是利用現(xiàn)有的組件根據(jù)特定的布局方式組成新的組件,大多繼承ViewGroup或者是各種lauout。其中包含子控件
自定義View
在特定需求中,我們需要自己實現(xiàn)特定的控件,一般繼承View,SurfaceView或者其他View。不包含子控件。
一般自定義View在大多數(shù)情況下都有替代方案,利用現(xiàn)有控件進(jìn)行組合之類,但是這樣可能對內(nèi)存消耗會過大。
流程
1.構(gòu)造函數(shù)
View的構(gòu)造函數(shù)有四個,分別有一個,兩個,三個,四個參數(shù)。
public void SloopView(Context context) {}
public void SloopView(Context context, AttributeSet attrs) {}
public void SloopView(Context context, AttributeSet attrs, int defStyleAttr) {}
public void SloopView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {}
有四個參數(shù)的不考慮,有三個參數(shù)的現(xiàn)在也不考慮。那就看有一兩個參數(shù)的構(gòu)造方法吧。
有一個參數(shù)的構(gòu)造方法是在代碼中new的時候調(diào)用的。
這樣回調(diào)用一個參數(shù)的構(gòu)造函數(shù)。
SloopView view new SloopView(this);
當(dāng)在布局文件中定義的時候就會調(diào)用兩個參數(shù)的構(gòu)造函數(shù)
<com.sloop.study.SloopView
android:layout_width"wrap_content"
android:layout_height"wrap_content"/>
2.測量View大?。╫nMeasure)
View的大小不僅由自身決定,還會受父控件影響,我們可以自己去測量并設(shè)定控件的大小。
測量View的大小使用的是onMesaure()函數(shù):
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthsize = MeasureSpec.getSize(widthMeasureSpec); //取出寬度的確切數(shù)值
int widthmode = MeasureSpec.getMode(widthMeasureSpec); //取出寬度的測量模式
int heightsize = MeasureSpec.getSize(heightMeasureSpec); //取出高度的確切數(shù)值
int heightmode = MeasureSpec.getMode(heightMeasureSpec); //取出高度的測量模式
}
確定一個控件的寬高有兩部分組成,widthsize 和widthmode
用寬度舉例widthMode,測量模式有三種,被定義在View的內(nèi)部類View.MeasureSpec中,
| 模式 | 描述 |
|---|---|
| UNSPECIFIED | 默認(rèn)值,父控件沒有給子空間任何限制,子空間可以設(shè)置為任意的大小 |
| EXACTLY | 表示父控件已經(jīng)確切的自定了子View的大小 |
| AT_MOST | 表示子View具體大小沒有尺寸限制,但是存在上限,上線一般為父View的大小 |
獲取的方式上邊代碼中也寫到了,用MeasureSpec的getSize獲取數(shù)值,getMode獲取模式
如果想對View的寬高進(jìn)行修改,需要調(diào)用setMeasureDimension(widthSize,heightSize)這個函數(shù),其中的參數(shù)就是修改后的寬高值。
3.確定View大小(onSizeChanged)
View大小有變化的時候,會調(diào)用這個方法,從這個方法中可以獲取到新老寬高的值。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//View最終的大小是w h
}
4.確定子View布局位置(onLayout)
這個方法用于確定子控件的位置,在自定義ViewGroup會用到,確定子控件的位置用的是子控件的layout函數(shù)
,也就是確定子控件的位置是在ouLayout()方法中循環(huán)去除子控件,然后通過計算得出每個子控件的位置坐標(biāo)值,然后用每個子控件的layout方法進(jìn)行位置確定。
child.layout(l, t, r, b);
| 參數(shù)值 | 對應(yīng)函數(shù) |
|---|---|
| l | getLeft(); |
| t | getTop(); |
| r | getRight(); |
| b | getBottom(); |

5.繪制內(nèi)容(onDraw)
onDraw()函數(shù)是事記的繪制的部分,使用canvas進(jìn)行繪圖
6.對外提供操作方法和監(jiān)聽回調(diào)
一般在OnTouchEvent()函數(shù)中點擊事件進(jìn)行處理,然后通過監(jiān)聽回調(diào)將事件傳到外部進(jìn)行處理。