1. 程式人生 > >Android學習—簡單自定義View(一)

Android學習—簡單自定義View(一)

最近手上不忙所以回顧了一下自己今年來所接觸和學習的東西,突然覺得寫部落格真是一個很好的方式,希望自己 可以堅持下去。

自定義View的流程

  • 建立自定義類繼承View,並重寫構造方法,構造方法總共有四種,我們暫時只需要繼承前兩種
public CircleView(Context context) {
    super(context);
}

public CircleView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
}

第一種構造方法是在你動態新增自定義View的時候使用 在這裡插入圖片描述

第二種構造方法是在xml中使用時呼叫

<example.com.testactivity.CircleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"/>
  • 重寫onDraw()方法
/**
 * 重寫繪製的方法
 * @param canvas
 */
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.parseColor("#018172")); // 1.設定背景色
    float radius=100;                 //半徑
    float x=100;
    float y=100;
    Paint paint=new Paint();            //例項化一個paint物件      畫筆
    paint.setColor(Color.WHITE);                    // 2.設定畫筆顏色
    paint.setStyle(Paint.Style.STROKE);         //空心,預設是實心
    canvas.drawCircle(x,y,radius,paint);        //指定繪製的形狀 畫圓

}

paint.setStyle(Paint.Style.STROKE)設定畫筆的風格,可以指定圓心是實心還是空心,該方法主要用於矩形和圓型

  • Style.FILL:實心

  • Style.FILL_AND_STROKE:同時顯示實心和空心

  • Style.STROKE:空心

  • 重寫onMeasure方法

/**
 - 作用:如果想在xml中實現自適應大小 就需要重寫該方法 給這個View一個原始大小值
 - @param widthMeasureSpec
 - @param heightMeasureSpec
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width=200;
    int height=200;            //設定View自適應的原始大小

    int HEIGHT_MODE=MeasureSpec.getMode(heightMeasureSpec);        // 1.根據提供的測量值(格式)提取模式(下述三個模式之一)    
    int HEIGHT_SIZE=MeasureSpec.getSize(heightMeasureSpec);         //2.根據提供的測量值(格式)提取大小值(這個大小也就是我們通常所說的大小)    
    int WIDTH_MODE=MeasureSpec.getMode(widthMeasureSpec);
    int WIDTH_SIZE=MeasureSpec.getSize(widthMeasureSpec);               

    if (HEIGHT_MODE==MeasureSpec.EXACTLY){                             //如果測量模式是精確模式 那麼直接使用獲取的值
        height=HEIGHT_SIZE;
    }else if (HEIGHT_MODE==MeasureSpec.AT_MOST){
        height=Math.min(height,HEIGHT_SIZE);                       //如果xml中設定的是wrap_content 即是該模式,取最小值
    }
    if (WIDTH_MODE==MeasureSpec.EXACTLY){
        width=WIDTH_SIZE;
    }else if (WIDTH_MODE==MeasureSpec.AT_MOST){
        width=Math.min(width,WIDTH_SIZE);
    }
    setMeasuredDimension(width,height);                   //測量完畢後 使用該方法設定真正的大小
}

注意:MeasureSpec.getMode(heightMeasureSpec) 表示獲取在xml中設定的高的模式 總共有三種模式

  • EXACTLY 精確模式 當設定的長度為match_parent或者給定一個具體大小時
  • AT_MOST 當設定為wrap_content時
  • UNSPECIFIED 該模式很少用到

參考連結