弧形进度条,用到PorterDuffXfermode

UI设计师的审美观特别的好,做的UI也很好看。

先看设计图要求


分析:

渐变可以做,文字也都没什么问题,但是圆环外边的小突起怎么做?用画小渐变矩形?没有进度的灰色带边框的渐变圆弧怎么做?

太难了,最终选择的是用图片来做

图片如下,只上传了上圆环


图:bgBitmap图:shadeBitmap图:混合模式

关键点就是PorterDuffXfermode 图层混合模式 PorterDuff.Mode.DST_OUT

原理:在画布最底层绘制bgBitmap,然后用shadeBitmap和一个圆弧叠加后的图层遮盖bgBitmap,就可以了。由于使用DST_OUT后圆弧和shadeBitmap重叠的部分,shadeBitmap就不会显示(透明的),bgBitmap就显示部分了。

下面就是代码了:

Xfermodem Xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);

@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bgBitmap, null, bgRect, mPaint1); 先绘制背景bgBitmap,使用shadeBitmap来遮盖背景bgBitmap

//绘制文字,没什么好说的
canvas.drawText("0", srcRect.left-mBound.width(),  srcRect.top+srcRect.height()/2+mBound.height()/2, textPaint);
canvas.drawText("15", srcRect.left-mBound.width(),  srcRect.top-10, textPaint);
canvas.drawText("30", srcRect.left+srcRect.width()/2-mBound.width()/2,  srcRect.top-mBound.height(), textPaint);
canvas.drawText("45", srcRect.left+srcRect.width(),  srcRect.top, textPaint);
canvas.drawText("60", srcRect.left+srcRect.width()+mBound.width(),  srcRect.top+srcRect.height()/2+mBound.height()/2, textPaint);
canvas.drawText("KW", UnitX-unitBound.width()/2, UnitY+unitBound.height()/2, unitPaint);
if(angle>=178){return;}

//将绘制操作保存到新的图层,因为图像合成是很昂贵的操作,将用到硬件加速,这里将图像合成的处理放到离屏缓存中进行
        int saveCount = canvas.saveLayer(dstRect, mPaint, Canvas.ALL_SAVE_FLAG);
        //绘制目标图
        canvas.drawBitmap(shadeBitmap, null, dstRect, mPaint1);

        //设置混合模式
        mPaint.setXfermode(mXfermode);
        //绘制源图,也就是圆弧
        canvas.drawArc(srcRect, 179, angle, false, mPaint);
        //清除混合模式
        mPaint.setXfermode(null);
        //还原画布
        canvas.restoreToCount(saveCount);
//上面的做法就是 把shadeBitmap和一个圆弧在一个图层中进行叠加,圆弧扫过的部分shadeBitmap就不会显示,然后把这个图层覆盖到canvas上,也就是bgBitmap上面,shadeBitmap不显示的部分,bgBitmap就显示出来了
       }

那么怎么控制进度呢?当然是控制angle啦,进度0-180 

这是生成绘画矩形的代码

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        int width = w>h?w:h;
        int centerX = width/2;
        int centerY = width/2;
        int quarterWidth = width /4;
        srcRect = new RectF(centerX-quarterWidth+25, centerY-quarterWidth+25, centerX+quarterWidth-25, centerY+quarterWidth-25);
        dstRect = new RectF(centerX-quarterWidth, centerY-quarterWidth, centerX+quarterWidth, centerY+quarterWidth);
        bgRect = new RectF(centerX-quarterWidth, centerY-quarterWidth, centerX+quarterWidth, centerY+quarterWidth);
        UnitX = centerX;
        UnitY = centerY;
}

初始化画笔的时候要设置mPaint1.setAntiAlias(true);mPaint1.setFilterBitmap(true);这样画出来的图形边缘就不会有齿了。

画圆弧的画笔要设置为空心mPaint.setStyle(Paint.Style.STROKE);

最终效果图:


附:在深圳做Android开发,第2个月,以前没做过Android开发,如有不足之处,请指出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值