android 自定义控件(五) 音量切换

转自:鸿洋博客,正在学习,非常感谢!
今天学习的是一个音量调节的demo:
最终效果图如下:

1.基本的属性设置:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="firstColor" format="color" />
    <attr name="secondColor" format="color" />
    <attr name="cicleWidth" format="dimension" />
    <attr name="bg" format="reference" />
    <attr name="docount" format="integer" />
    <attr name="splitSize" format="dimension" />

    <declare-styleable name="CustomeView4">
        <attr name="firstColor" />
        <attr name="secondColor" />
        <attr name="cicleWidth" />
        <attr name="bg" />
        <attr name="docount" />
        <attr name="splitSize" />

    </declare-styleable>

</resources>

2.自定义view:
先初始化我们自己设置的属性:

 TypedArray a=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomeView4,defStyleAttr,0);
        int n=a.getIndexCount();
        for (int i=0;i<n;i++){
            int attr=a.getIndex(i);
            switch (attr){
                case  R.styleable.CustomeView4_firstColor:
                    firstColor=a.getColor(attr,Color.RED);
                    break;
                case R.styleable.CustomeView4_secondColor:
                    secondColor=a.getColor(attr,Color.BLUE);
                    break;
                case R.styleable.CustomeView4_cicleWidth:
                    cicleWidth=a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,10,getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomeView4_docount:
                    doCount=a.getInt(attr,20);//绘制20个
                    break;
                case R.styleable.CustomeView4_splitSize:
                    splitSize=a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,10,getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomeView4_bg:
                    bg= BitmapFactory.decodeResource(getResources(),a.getResourceId(attr,0));
                    break;
            }

        }
        a.recycle();

现在开始绘制,首先我们可以看出内部是一个圆包裹一个图片,所以整个view的基本区域还是一个圆:

        mPaint.setColor(firstColor);
        mPaint.setStrokeWidth(cicleWidth);
        mPaint.setAntiAlias(true);

        int center=getWidth()/2;//圆心位置
        int radius=center-cicleWidth/2;
        canvas.drawCircle(center,center,radius,mPaint);

绘制出一个圆:
这里写图片描述
这个是基本区域,现在我们再绘制一个中心图片,就是音量图标:

        rect.left=center-bg.getWidth()/2;
        rect.right=center+bg.getWidth()/2;
        rect.top=center-bg.getHeight()/2;
        rect.bottom=center+bg.getHeight()/2;
        canvas.drawBitmap(bg,null,rect,mPaint);

结果如下:
这里写图片描述

现在绘制音量大小:
我们首先要的是一个圆环:
a.只要设置绘制的style是STROKE就可以变成空心的
这里写图片描述
然后设置中间的间隙,注意开始的时候我用的是绘制圆,但是后期要是一段段的隔开就要变成圆弧,根据数目绘制一定的圆弧。

  //绘制小块块
    private void drawSpan(Canvas canvas, int radius, int center) {

        //根据需要绘制的块块数目来计算间隙,以及在每一个小块块的长,这里是按照一个圆就是一个“单位1”
        float itemSize=(360-doCount*splitSize)/doCount;//需要绘制的个数

        rectF.left=center-radius;
        rectF.right=center+radius;
        rectF.top=center-radius;
        rectF.bottom=center+radius;
        //设置圆环的颜色
        mPaint.setColor(firstColor);
        for(int i=0;i<doCount;i++){
            canvas.drawArc(rectF,i*(splitSize+itemSize),itemSize,false,mPaint);
        }

    }

这里写图片描述
这个时候我们发现我们的小块块并不是圆头的,这是因为开始的时候没有给画笔设置这个属性

  mPaint.setStrokeCap(Paint.Cap.ROUND);

注意每一个小块块的大小和数据以及要绘制的总数要合理分配,否则就会挤在一起:
这里写图片描述
最终样式:
这里写图片描述
这里我们要绘制中心图片,所以还要考虑的问题就是图片的大小,如果图片太大就绘制成为最大的内切正方形否则就绘制在中心位置,所以在这里我们需要设置内切正方形也就是中间图片的绘制区域,这里的图片大还是不大取决于我们的最大内切正方形小于这个值的都设置在中心位置:
这里写图片描述

        int r=radius-cicleWidth/2;//内切正方形的圆
        rect.left= (int) (r- Math.sqrt(2)/2*r+cicleWidth);
        rect.right= (int) (rect.left+Math.sqrt(2)*r);
        rect.top=(int) (r- Math.sqrt(2)/2*r+cicleWidth);
        rect.bottom=(int) (rect.left+Math.sqrt(2)*r);

        //如果图片太小绘制在中间
        if(bg.getWidth()<Math.sqrt(2)*r){
            rect.left=r-bg.getWidth()/2+cicleWidth;
            rect.right= rect.left+bg.getWidth();
            rect.top=r-bg.getHeight()/2+cicleWidth;
            rect.bottom=rect.top+bg.getHeight();
        }

        canvas.drawBitmap(bg,null,rect,mPaint);

最终效果
这里写图片描述


笔记:
//定义线段断电形状为圆头
mPaint.setStrokeCap(Paint.Cap.ROUND);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值