android--------自定義控件 之 方法篇

前面簡單的講述了Android中自定義控件的理論和流程圖,今天經過代碼來詳細的講解一下其中的方法html

 

首先先建立一個類 CircularView 繼承於 View,以後實現構造方法(初始化步驟)java

public class CircularView extends View {
public CircularView(Context context) {
        super(context);
    }

    public CircularView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CircularView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CircularView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}

View的構造函數有四種重載,View構造函數的參數有多有少,android

有四個參數的構造函數在API21的時候才添加上,暫不考慮。canvas

有三個參數的構造函數中第三個參數是默認的Style,這裏的默認的Style是指它在當前Application或Activity所用的Theme中的默認Style,且只有在明確調用的時候纔會生效ide

//調用了三個參數的構造函數,明確指定第三個參數
  this(context, attrs, com.android.internal.R.attr.imageButtonStyle);

因爲三個參數的構造函數第三個參數通常不經常使用,因此也暫不考慮函數

//通常在直接New一個View的時候調用。
public void CircularView(Context context) {}

//通常在layout文件中使用的時候會調用,關於它的全部屬性(包括自定義屬性)都會包含在attrs中傳遞進來。
public void CircularView(Context context, AttributeSet attrs) {}

使用方式:(佈局文件中)佈局

<com.zhangqie.customcontrol.demo1.CircularView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@color/colorAccent"
        />

onMeasure方法 (測量View大小)this

View的大小不只由自身所決定,同時也會受到父控件的影響,爲了咱們的控件能更好的適應各類狀況,通常會本身進行測量。code

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthsize  MeasureSpec.getSize(widthMeasureSpec);      //取出寬度的確切數值
    int widthmode  MeasureSpec.getMode(widthMeasureSpec);      //取出寬度的測量模式
    
    int heightsize  MeasureSpec.getSize(heightMeasureSpec);    //取出高度的確切數值
    int heightmode  MeasureSpec.getMode(heightMeasureSpec);    //取出高度的測量模式
}

從上面能夠看出 onMeasure 函數中有 widthMeasureSpec 和 heightMeasureSpec 這兩個 int 類型的參數, 毫無疑問他們是和寬高相關的, 但它們其實不是寬和高, 而是由寬、高和各自方向上對應的測量模式來合成的一個值:htm

 

測量模式一共有三種, 被定義在 Android 中的 View 類的一個內部類View.MeasureSpec中:

模式 二進制數值 描述
UNSPECIFIED 00 默認值,父控件沒有給子view任何限制,子View能夠設置爲任意大小。
EXACTLY 01 表示父控件已經確切的指定了子View的大小。
AT_MOST 10 表示子View具體大小沒有尺寸限制,可是存在上限,上限通常爲父View大小。

 

 

onSizeChanged方法 肯定View的大小,這個函數在視圖大小發生改變時調用

/***
     * 肯定View的大小(這個函數在視圖大小發生改變時調用。)
     *
     * 寬度,高度,上一次寬度,上一次高度。
     * 只需關注 寬度(w), 高度(h) 便可,這兩個參數就是View最終的大小。
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.i(TAG,"onSizeChanged");
    }

onLayout 方法 肯定子View佈局位置

/****
     * 佈局-Layout過程用於設置視圖在屏幕中顯示的位置,onLayout通常只會在自定義ViewGroup中才會使用
     *
     * @param changed
     * @param left
     * @param top
     * @param right
     * @param bottom
     */
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        Log.i(TAG,"onLayout");
    }

肯定佈局的函數是onLayout,它用於肯定子View的位置,在自定義ViewGroup中會用到,他調用的是子View的layout函數。

在自定義ViewGroup中,onLayout通常是循環取出子View,而後通過計算得出各個子View位置的座標值,而後用如下函數設置子View位置。

 

onDraw 方法,繪製內容

 

/***
     * 繪製-draw過程主要用於利用前兩步獲得的參數,將視圖顯示在屏幕上,到這裏也就完成了整個的視圖繪製工做
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

onDraw是實際繪製的部分,也就是咱們真正關心的部分,使用的是Canvas繪圖。

相關文章
相關標籤/搜索