自定義View(二)分類、流程

自定義View繪制流程

其中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); //取出高度的測量模式
}

確定一個控件的寬高有兩部分組成,widthsizewidthmode
用寬度舉例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)行處理。

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

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

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