android自定义控件

这里实现一个饼图自定义控件View :
第一步:
在values中创建attrs.xml 属性文件如下;




    
        
        
    


第二步:
继承View控件实现之定义控件:

public class CustomView extends View {

    private String TAG="IMListView";
    private Paint mPaint;
    private RectF oval;
    private int start_angle;
    private float move_angle;

    public CustomView(Context context) {
        super(context);
        init(context,null);
    }

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

    public CustomView(Context context,  @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    private void init(Context context,AttributeSet attributeSet){
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        oval=new RectF();
        if (attributeSet!=null) {
            TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.CustomView);
            int indexCount = typedArray.getIndexCount();
            for (int i = 0; i < indexCount; i++) {
                int index = typedArray.getIndex(i);
                if (index==R.styleable.CustomView_start_angle)
                {
                    start_angle = typedArray.getInteger(index, 180);
                }
                if (index==R.styleable.CustomView_move_angle)
                {
                    move_angle = typedArray.getFloat(index, 135f);
                }
            }
            typedArray.recycle();
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wmode = MeasureSpec.getMode(widthMeasureSpec);
        int hmode = MeasureSpec.getMode(heightMeasureSpec);
        int wsize = MeasureSpec.getSize(widthMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        switch (wmode) {
            case MeasureSpec.AT_MOST:
                Log.i(TAG, "onMeasure: AT_MOST");
                break;
            case MeasureSpec.EXACTLY:
                Log.i(TAG, "onMeasure: EXACTLY");
                break;
            case MeasureSpec.UNSPECIFIED:
                Log.i(TAG, "onMeasure: UNSPECIFIED");
                break;
        }
        Log.i(TAG, "onMeasure: width:"+wsize+"--height:"+ size);
    }

    @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: "+changed);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.GRAY);
        // FILL填充, STROKE描边,FILL_AND_STROKE填充和描边
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        int with = getWidth();
        int height = getHeight();
        Log.e(TAG, "onDraw---->" + with + "*" + height);
        float radius = with / 4;
        canvas.drawCircle(with / 2, with / 2, radius, mPaint);
        mPaint.setColor(Color.BLUE);
        oval.set(with / 2 - radius, with / 2 - radius, with / 2
                + radius, with / 2 + radius);//用于定义的圆弧的形状和大小的界限
        canvas.drawArc(oval, start_angle, move_angle, true, mPaint);  //根据进度画圆弧
    }
}

说明:
onMeasure是测绘控件吃存并且设置宽度和高度属性的方法,检测中有三种模式;
(1) UPSPECIFIED :父容器对于子容器没有任何限制,子容器想要多大就多大.
(2) EXACTLY父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.
(3) AT_MOST子容器可以是声明大小内的任意大小.

onLayout是布局方法,主要用户ViewGroup布局子控件的方法。

onDraw是绘制显示内容的方法,在View他是空方法,在其他控件中有具体的逻辑。

init方法是来获取上面声明自定义属性的值。

第三步:
调用布局自定义控件:


其中app:要在布局中声明例如:
xmlns:app="http://schemas.android.com/apk/res-auto"
也可以直接在控件布局中声明:


你可能感兴趣的:(android自定义控件)