android 自定义view(二),继承view

现在我们来举例讲解自定义的第一种,继承view,效果如下图示:

这里写图片描述
直接看代码:

public class CircleView extends View {

    private int width;
    private int height;
    private Paint mPaint;
    private RectF mRect;

    //定义两个数组,一个表达大小,一个表示颜色
    private int[] itemCount={11,22,33,44,55};
    private int[] itemColor={Color.BLUE,Color.GREEN,Color.RED,Color.YELLOW,Color.GRAY};


    public CircleView(Context context) {
        this(context,null);
    }

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

    private void initCanvas(Context context) {
        mPaint=new Paint();
        mRect= new RectF();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);

    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        switch (widthMode){
            case MeasureSpec.EXACTLY://match_parent and 具体的值
                width=widthSize;
                break;
            case MeasureSpec.AT_MOST://wrap_content;
                width=getScreenHeight(getContext())/2;
                break;
        }
        height=width;

        setMeasuredDimension(width,height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mRect.left=getLeft();
        mRect.top=getTop();
        mRect.right=getRight();
        mRect.bottom=getBottom();

        float xWidth=mRect.right-mRect.left;
        float xHeight=mRect.bottom-mRect.top;

        float radis;

        if(xWidth>xHeight){
            radis=xHeight/2;
        }else{
            radis=xWidth/2;
        }

        int total=11+22+33+44+55;
        float start = 0.0f;
        for (int i = 0; i < 5; i++) {
            //draw pie
            mPaint.setColor(itemColor[i]);
            float sweep = (float) itemCount[i] / total * 360;
            canvas.drawArc(mRect,start,sweep,true,mPaint);
            start += sweep;
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    /**
     * 获得屏幕宽度
     *
     * @param context
     * @return
     */
    public  int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.heightPixels;
    }

}

可以看到,继承自view的主要重写onMeasure和onDraw方法就可以了,onLayout主要继承viewGroup时重写的较多。
在onMeasure方法中,我们有了个简单的判断,主要是为了防止xml布局中宽,长的属性是wrap_content,此时我们默认的圆的半径是屏幕宽的一半。
setMeasuredDimension(width,height);是一个非常重要的方法,真正设置view的大小就是这个方法最终拍板的。

在onDraw方法中,主要是在绘制我们需要的效果图。对paint和canvas不熟悉的人需要加强这部分的知识,因为最定义view最重要的就是自己的绘制,必须要熟悉这些相关的类。
canvas.drawArc(mRect,start,sweep,true,mPaint);就是这个画扇形的方法最后组成了我们想要的一个圆。

细心的小伙伴也许可以发现,如果我在xml中对该view的位置进行一个简单的设置,比如让其居中,此时的扇形甚至都不会出现,这问题主要是出现在canvas.drawArc(mRect,start,sweep,true,mPaint)的mRect这个参数上,这个区域应该是一个相对区域而不是具体的。所以此时的mRect的参数应该这样写:

  mRect.left=0;
  mRect.top=0;
  mRect.right=mRect.left+width;
  mRect.bottom=mRect.top+width;

所以我们需要对paint和canvas的api有足够的了解才能自定义出符合要求的view。
下一篇文章 自定义view(二)继承viewgroup,欢迎大家阅读评论。

最近搞了个Android技术分享的公众号,欢迎关注投稿。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值