Android自定義ProgressDialog之仿WIN8進度條

仿照win8的進度條自定義了一個progressbar,進度條默是白色,修改android:background屬性可以設置進度條顏色。截了幾張圖,一些細節模仿地還不夠到位:

/**
 * 圓形進度條
 * @author planet
 *
 */
public class IndeterminateProgressBar  extends View{
	static final String TAG = "ProgressBar";
	/**
	 * 幀率=1000/delayMillis
	 * 幀率越快,旋轉速度也就越快
	 */
	private int delayMillis = 30;
	private Handler mHandler;
	private ArrayList<Entity> entities;
	private int width = 0;
//	private int height = 0;
	private int r = 15;
	private int shift = 20;
	private int radius = 3;
	private int color = Color.WHITE;
	private long time = 0;
	private boolean started = false;

	public IndeterminateProgressBar(Context context) {
		super(context);
		init(null);
	}

	public IndeterminateProgressBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs);
	}
	public IndeterminateProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(attrs);
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		width = getLayoutParams().width;
//		height = getLayoutParams().height;
		if(width>0){
			//根據view寬度定義小球的半徑
			if(width<50){
				radius = 2;
			}else if(width<80){
				radius = 3;
			}else{
				radius = 4;
			}
			//radius = width<80?2:4;
			r = width/2-radius*2;
			if(r<=0) r = 15;
			shift = width/2;
		}
	}

	private void init(AttributeSet attrs){
		//獲取設置的background作爲小球顏色,然後將view自身背景設置成透明色
		if(attrs != null){
			String v = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "background");
			if(v != null){
				if(v.startsWith("#")){
					color = Color.parseColor(v);
				}else{
					color = getResources().getColor(Integer.parseInt(v.replaceAll("@", "")));
				}
			}
			setBackgroundResource(android.R.color.transparent);
		}

		mHandler = new Handler(new Handler.Callback() {
			@Override
			public boolean handleMessage(Message msg) {
				for(Entity e : entities){
					e.update();
				}
				invalidate();
				mHandler.sendEmptyMessageDelayed(0, delayMillis);
				time += delayMillis;
				return false;
			}
		});
	}
	
	public void setColor(int color){
		this.color = color;
	}
	/**
	 * 結束動畫
	 */
	public void stop(){
		mHandler.removeMessages(0);
		started = false;
		invalidate();
	}
	
	public boolean isStart(){
		return started;
	}
	/**
	 * 重新開始動畫
	 */
	public void start(){
		if(started) return;
		started = true;
		time = 0;
		entities = new ArrayList<IndeterminateProgressBar.Entity>();
		float s = .25f;
		entities.add(new Entity(0, color, 0));
		entities.add(new Entity(1*s, color, delayMillis*4));
		entities.add(new Entity(2*s, color, delayMillis*8));
		entities.add(new Entity(3*s, color, delayMillis*12));
		entities.add(new Entity(4*s, color, delayMillis*16));
		mHandler.sendEmptyMessage(0);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		for(Entity e : entities){
			e.draw(canvas);
		}
		super.onDraw(canvas);
	}

	class Entity{
		private float x;
		private float y;
		private int color;
		private Paint paint;
		private double sp = 0;
		private long delay;
		//動畫一共三個階段0~2
		private int sec = 0;
		//每個階段pec從0~1
		private float pec = 0;
		boolean visiable = true;

		public float getInterpolation(float input) {
			return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
		}

		public Entity(float sp, int color, int delay) {
			paint = new Paint();
			paint.setAntiAlias(true);
			paint.setStyle(Paint.Style.FILL);
			this.color = color;
			this.sp = sp;
			this.delay = delay;
			paint.setColor(this.color);
		}

		public void update(){
			if(time<delay) return;
			visiable = true;
			//pec這個變量是步進值,值越大,旋轉速度也越快,可以跟delayMillis配合使用
			pec+= 0.03;
			if(pec>1){
				pec = 0;
				sec=++sec==3?0:sec;
				delay = sec==0?time+delayMillis*22:time+delayMillis*3;
				visiable = sec==0?false:true;
			}
			//sec=0從0.5pi開始,sec=1從1.5pi開始,sec=2從1pi開始
			double θ = Math.PI*.5+(sec==0?0:sec*Math.PI/sec) - (sec==0?0:sp)
					//sec=0,sec=2移動1pi, sec=1移動2pi
					+ (Math.PI*(sec==1?2:1)- (sec==0?sp:0) + (sec==2?sp:0))*getInterpolation(pec);
			x = (float) (r/2*Math.cos(θ))+shift/2;
			y = (float) (r/2*Math.sin(θ))+shift/2;
		}

		public void draw(Canvas canvas){
			if(!visiable || x==0 || y==0) return;
			canvas.save();
			canvas.translate(x, y);
			canvas.drawCircle(x, y, radius, paint);
			canvas.restore();
		}
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		if(getVisibility() == View.VISIBLE){
			start();
		}
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		stop();
	}
}



源碼地址:http://download.csdn.net/detail/u014676619/8756535

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章