本篇主要介绍怎么利用两张图片去实现圆形进度条
其实实现圆形进度条很简单,自定义View,画出一个环,然后控制遮罩环就可以了
但是用画笔画的环很不好控制大小,<因为适配这个问题,所以用像素控制不很乐观>
所以最好使用两张图片去控制进度条的显示岂不是就解决了适配的问题
问题来了,那要怎么实现啊,小伙伴们肯定火大了,那不废话嘛,明显用图片遮罩啊!
嗯,对,就是用遮罩,可是在网上找了一圈也没发现使用两张图片遮罩实现圆形进度条,都是各种画圆。
也是悲催了,于是乎,笔者就耐不住了,自己动手,丰衣足食
首先呢,看看效果图吧!,触屏增加进度
/** * 利用View的相交模式,实现两种圆形图片的进度条 * */ public class MyView extends View { private Bitmap bmpBg; private Bitmap bmpForbg; private PorterDuffXfermode mMode ; private Paint mXferPaint ; private RectF mOval ; private int mPercent; private Paint paint ; private Rect targetRect ; private FontMetricsInt fontMetrics ; /** * 重写父类构造函数 * * @param context */ public MyView(Context context) { super(context); setFocusable(true); // setFocusableInTouchMode(true); bmpBg = (Bitmap) BitmapFactory.decodeResource(getResources(), R.drawable.ic_set_download_speed1); bmpForbg = (Bitmap) BitmapFactory.decodeResource(getResources(), R.drawable.ic_set_download_speed2); mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); // mXferPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mXferPaint = new Paint(); // mXferPaint.setStyle(Paint.Style.FILL); mXferPaint.setColor(Color.RED); mXferPaint.setXfermode(mMode); mOval = new RectF(); mOval.left = 0; mOval.top = 0; mPercent = 0 ; paint = new Paint() ; paint.setColor(getResources().getColor(R.color.pr2)) ; paint.setTextSize(24) ; targetRect = new Rect(100, 100, 100 + bmpBg.getWidth(), 100 + bmpBg.getHeight()); fontMetrics = paint.getFontMetricsInt(); } /** * 重写父类绘图函数 */ @Override protected void onDraw(Canvas canvas) { mXferPaint.setXfermode(null); canvas.drawBitmap(bmpBg, 100, 100, mXferPaint) ; int saveCount = canvas.saveLayer(100, 100, 100 + bmpBg.getWidth(), 100 + bmpBg.getHeight(), null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); mOval.left = 100 ; mOval.top = 100 ; mOval.right = 100 + bmpBg.getWidth(); mOval.bottom = 100 + bmpBg.getHeight(); mXferPaint.setXfermode(null); canvas.drawArc(mOval, -90, 360 * mPercent / 100, true, mXferPaint); mXferPaint.setXfermode(mMode); canvas.drawBitmap(bmpForbg, 100, 100, mXferPaint); canvas.restoreToCount(saveCount); int baseline = targetRect.top + (targetRect.bottom - targetRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top; // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() paint.setTextAlign(Paint.Align.CENTER); canvas.drawText(mPercent + "%", targetRect.centerX(), baseline, paint); } @Override public boolean onTouchEvent(MotionEvent event) { mPercent ++ ; mPercent %= 100 ; // 重绘画布 invalidate(); // postInvalidate(); return true; } }
private Bitmap bmpBg; private Bitmap bmpForbg;然后呢,定义操作图片的画笔mXferPaint,以及显示区域mOval<备注:因为显示区域是扇形的,所以当然是Oval了>
private PorterDuffXfermode mMode ; private Paint mXferPaint ; private RectF mOval ;接着就定义一个需要控制进度的变量
private int mPercent;最后就剩下中间显示进度的文字了,targetRect和fontMetrics是为了使文字居中显示,大家可以先不管
private Paint paint ; private Rect targetRect ; private FontMetricsInt fontMetrics ;接着就是初始化操作了
public MyView(Context context) { super(context); setFocusable(true); // setFocusableInTouchMode(true); bmpBg = (Bitmap) BitmapFactory.decodeResource(getResources(), R.drawable.ic_set_download_speed1); bmpForbg = (Bitmap) BitmapFactory.decodeResource(getResources(), R.drawable.ic_set_download_speed2); mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); // mXferPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mXferPaint = new Paint(); // mXferPaint.setStyle(Paint.Style.FILL); mXferPaint.setColor(Color.RED); mXferPaint.setXfermode(mMode); mOval = new RectF(); mOval.left = 0; mOval.top = 0; mPercent = 0 ; paint = new Paint() ; paint.setColor(getResources().getColor(R.color.pr2)) ; paint.setTextSize(24) ; targetRect = new Rect(100, 100, 100 + bmpBg.getWidth(), 100 + bmpBg.getHeight()); fontMetrics = paint.getFontMetricsInt(); }
<span style="white-space:pre"> </span>mXferPaint.setXfermode(null); canvas.drawBitmap(bmpBg, 100, 100, mXferPaint) ;接下来定制Oval区域,然后绘制前景图
int saveCount = canvas.saveLayer(100, 100, 100 + bmpBg.getWidth(), 100 + bmpBg.getHeight(), null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); mOval.left = 100 ; mOval.top = 100 ; mOval.right = 100 + bmpBg.getWidth(); mOval.bottom = 100 + bmpBg.getHeight(); mXferPaint.setXfermode(null); canvas.drawArc(mOval, -90, 360 * mPercent / 100, true, mXferPaint); mXferPaint.setXfermode(mMode); canvas.drawBitmap(bmpForbg, 100, 100, mXferPaint); canvas.restoreToCount(saveCount);终点终于来了,就是操控另一只画笔涂写文体了
<span style="white-space:pre"> </span>int baseline = targetRect.top + (targetRect.bottom - targetRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top; // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX() paint.setTextAlign(Paint.Align.CENTER); canvas.drawText(mPercent + "%", targetRect.centerX(), baseline, paint);
@Override public boolean onTouchEvent(MotionEvent event) { mPercent ++ ; mPercent %= 100 ; // 重绘画布 invalidate(); // postInvalidate(); return true; }
invalidate();//这个可不能少,是刷新画布