Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 一個規范的自定義View——Android開發藝術探索筆記

一個規范的自定義View——Android開發藝術探索筆記

編輯:關於android開發

一個規范的自定義View——Android開發藝術探索筆記


一個不規范的自定義View

這個自定義的View很簡單,就是畫一個圓,實現一個圓形效果的自定義View。

先看一個不規范的自定義View是怎麼做的

public class CircleView extends View {

    private int mColor = Color.RED;
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public CircleView(Context context) {
        super(context);
        init();
    }

    public CircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    private void init() {
        mPaint.setColor(mColor);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        int radius = Math.min(width, height) / 2;
        canvas.drawCircle(width / 2, height / 2, radius, mPaint);
    }
}

對應的xml

這樣雖然也能畫出一個圓來,但是這並不是一個規范的自定義View,主要存在以下問題:

android:padding屬性是不能使用的 使用wrap_content就相當於使用match_partent

一個規范的自定義View

為了解決以上問題需要重寫View的onMeasure和onDraw方法。

完整代碼如下:

public class CircleView extends View {

    private int mColor = Color.RED;
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public CircleView(Context context) {
        super(context);
        init();
    }

    public CircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleView);
        mColor = a.getColor(R.styleable.CircleView_circle_color, Color.RED);
        a.recycle();
        init();
    }

    private void init() {
        mPaint.setColor(mColor);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.AT_MOST
                && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, 200);
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, heightSpecSize);
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, 200);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        int width = getWidth() - paddingLeft - paddingRight;
        int height = getHeight() - paddingTop - paddingBottom;
        int radius = Math.min(width, height) / 2;
        canvas.drawCircle(paddingLeft + width / 2, paddingTop + height / 2,
                radius, mPaint);
    }
}

添加自定義屬性

在values文件夾下添加attrs.xml



    
        
    

自定義的屬性集合CircleView,在這個屬性集合裡只定義了一個格式為color的屬性circle_color。

在View的構造函數中解析自定義的屬性

 public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleView);
        mColor = a.getColor(R.styleable.CircleView_circle_color, Color.RED);
        a.recycle();
        init();
    }

在布局文件中使用自定義屬性

   

在使用自定義的屬性時,要在schemas聲明:xmlns:app=”http://schemas.android.com/apk/res-auto”,使用時與普通屬性類似,app:circle_color=”@color/light_green” 。

自定義View須知

自定義的View中margin屬性可以使用,因為它是由父容器控制的 直接繼承View或ViewGroup的需要自己處理wrap_content View要在onDraw方法中要處理padding,而ViewGroup要在onMeasure和onLayout中處理padding和margin View中的post方法可以取代handler 在View的onDetachedFromWindow中停止動畫,防止內存洩露 有滑動嵌套情形時,注意滑動沖突處理 

想要自定義出漂亮的View並不容易,只有多讀,多寫,多測,才能更好的掌握。自己造一個輪子,然後再對比成熟的輪子去找差距和不足。

歡迎轉載,轉載請注明原文鏈接http://blog.csdn.net/l664675249/article/details/50787973

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved