最近做项目,有个一个需求,就是圆角进度条。效果图如下。
当时项目时间很紧,没多去想怎么实现最佳,就直接把美工给的圆角进度条裁剪成了四份。来做 Canvas 剪切绘制。这样虽然也能达到效果,但是服用性很差。最近网上搜索了很长时间,发现Paint画笔,有遮挡层的功能。android.graphics.Paint.setXfermode(Xfermode xfermode) 。其中一个参数就是
Mode.DST_OUT 显示底图与上层图非交集的底图图像。于是就有个思路,先绘制圆角矩形进度条,然后设置画笔遮挡属性,再绘制扇形,来遮罩圆角矩形。这样就可以实现圆角矩形进度条的功能了。
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{ SurfaceHolder mSurfaceHolder; boolean isRun; /** 进度条背景**/ Bitmap bmpDes; /** 移动角度**/ float m = 0; /** 包围进度条背景的圆半径**/ float r; /** 移动速度**/ float speed; public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub mSurfaceHolder = this.getHolder(); mSurfaceHolder.addCallback(this); /** 加载进度条**/ bmpDes = BitmapFactory.decodeResource(getResources(), R.drawable.d1).copy(Bitmap.Config.ARGB_8888, true); /** 计算半径**/ r = (float) Math.sqrt(Math.pow(bmpDes.getWidth()/2, 2) + Math.pow(bmpDes.getHeight()/2, 2)); /** 根据25s,计算移动速度**/ speed = (float) (360 / (25000 / 33.0)); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub isRun = true; new Thread(){ public void run(){ while(isRun){ long start = System.currentTimeMillis(); Canvas canvas = null; synchronized (mSurfaceHolder) { canvas = mSurfaceHolder.lockCanvas(); if(canvas != null ){ onGameDraw(canvas); if(canvas != null && mSurfaceHolder != null){ mSurfaceHolder.unlockCanvasAndPost(canvas); } m += speed; if(m >= 360) m = 0; } } long end = System.currentTimeMillis() - start; if(end < 33){ try { Thread.sleep(end); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }.start(); } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub isRun = false; } private void onGameDraw(Canvas canvas){ /* canvas.drawColor(Color.BLACK); c = new Canvas(bmpDes); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT)); int sc = c.saveLayer(0, 0, bmpDes.getWidth(), bmpDes.getHeight(), null, LAYER_FLAGS); c.drawArc(new RectF(-(r - bmpDes.getWidth()/2), -(r - bmpDes.getHeight()/2), r*2, r*2), 0, m, true, paint); c.restoreToCount(sc); canvas.drawBitmap(bmpDes, 0, 0, null);*/ canvas.drawColor(Color.BLACK); Paint paint = new Paint(); paint.setFilterBitmap(false); // 绘制第二层 int sc = canvas.saveLayer(0, 0, 0 + bmpDes.getWidth(), 0 + bmpDes.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); // 绘制进度条背景 canvas.drawBitmap(bmpDes, 0, 0, paint); // 设置遮挡属性 paint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT)); // 绘制遮挡扇形 canvas.drawArc(new RectF(-(r - bmpDes.getWidth()/2), -(r - bmpDes.getHeight()/2), r*2, r*2), 0, m, true, paint); // 将第二层反馈给画布 canvas.restoreToCount(sc); } }
源码
http://download.csdn.net/detail/li_xiao_kang/8750631 点击打开链接
原文地址:http://blog.csdn.net/li_xiao_kang/article/details/46225927