android圆角矩形进度条

最近做项目,有个一个需求,就是圆角进度条。效果图如下。

当时项目时间很紧,没多去想怎么实现最佳,就直接把美工给的圆角进度条裁剪成了四份。来做 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  点击打开链接

时间: 2024-11-07 17:44:39

android圆角矩形进度条的相关文章

Android自定义圆角矩形进度条2

效果图: 或 方法讲解: (1)invalidate()方法 invalidate()是用来刷新View的,必须是在UI线程中进行工作.比如在修改某个view的显示时, 调用invalidate()才能看到重新绘制的界面.invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉.一般在自定义控件中会用到这个方法. (2)RectF方法的应用 RectF是用来绘画矩形的方法. RectF(left,top,right,bottom),四个参数的含义分别是父控件距离矩形左上右下

【转】24. android dialog ——ProgressDialog 进度条对话框详解

原文网址:http://blog.csdn.net/jamesliulyc/article/details/6375598 首先在onCreateDialog方法里创建一个ProgressDialog,如下: [java] view plaincopy //this表示该对话框是针对当前Activity的 progressDialog = new ProgressDialog(this); //设置最大值为100 progressDialog.setMax(100); //设置进度条风格STYL

Android 中带有进度条效果的按钮(Button)

安卓中带有进度条效果的按钮,如下图: 1.布局文件如下activity_main.xml 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="fill_parent" 4 android:layo

[Android]组件之进度条2

这个例子不错,详细讲解了alertdialog及LayoutInflater的用法: main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:lay

Android——菜单和进度条

xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent&quo

android中的进度条

Android中有多种进度条,如转圈的圆环,水平线的进度条.可拉伸的进度条等,各种进度条关系如下 SeekBar是可拉伸的进度条,RatingBar是用于评分的进度条,都属于ProgressBar的子类 ProgressBar有多种风格,如Horizontal.Small.Large.Inverse等 进度条的主要属性 进度条最大值:max 当前进度:progress 次要进度的值:SecondaryProgress progressbar.isIndeterminate(); 用于判断进度条是

android快递跟踪进度条

android 快递跟踪进度条 activity.class import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; public class MainActivity extends

Android View 之进度条+拖动条+星级评论条....

PS:将来的你会感谢现在奋斗的自己.... 学习内容: 1.进度条 2.拖动条 3.星级评论条 1.进度条...       进图条这东西想必大家是很熟悉的...为了使用户不会觉得应用程序死掉了,因此为之设置一个进度条使应用程序的运行状态更好的反馈给客户...这也就是进度条的作用...因此一般的应用程序都会加入进度条...进度条分为圆形进度条和线性的进度条...目的都是一样的,只是展示的效果是不同的...用代码讲解一下... <LinearLayout xmlns:android="htt

Android webview 显示进度条

代码: ProgressDialog dialog = null; /** * 嵌入浏览器 */ private void embedBrowser(String url) { Log.i(TAG, url); WebView browser = (WebView) this.findViewById(R.id.c131_webkit); if (browser != null) { wifi = new WifiService(this); if (wifi.isNetworkConnecte