一個規範的自訂View——Android開發藝術探索筆記

來源:互聯網
上載者:User

一個規範的自訂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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.