1. 程式人生 > >Android自定義View實戰-100行帶你寫出SwitchButton

Android自定義View實戰-100行帶你寫出SwitchButton

1 序言

網上很多自定義View的例子都非常詳細講解了如何寫出一個高效實用的自定義View,但是這些由於過於詳細,給予一些新手的學習造成了一定的困難,比如說,當初我要學習如何自定義下拉重新整理控制元件,結果,很多大神順便把一些在我看來 學習自定義View非必要的技術帶了進來,如資料結構啊,事件分發機制啊.這些東西不是說不必要,但是他們應該放到別的文章裡面,否則對新手來說,讓他們去思考這些繁雜的機制,而容易陷入細節不能自拔.這些技術在這篇文章裡,他們只是充當輔助的角色,不是我們的主角,我們的主角就是在ondraw裡面花時間,然後寫出來一個自定義View.這樣我們就能更加專注寫出一個View,在此基礎上,我們再談擴充套件和高效.

2 實現思路


我們首先觀察一下,這個按鈕在開啟和關閉時的狀態,最終可以發現,他只是一些簡單的幾何組合,所以我們可以通過程式碼來實現這個效果,

3 程式碼

public class SwithcButton extends View {

	private Paint mPaint;
	public int state=1;  //狀態,0位開,1位關.預設為關閉狀態
	
	
	public SwithcButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		mPaint=new Paint();
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			
			postInvalidate();
			isAnim=true;
			break;

		default:
			break;
		}
		
		return true;
	}
	boolean isAnim;		//是否在播放動畫
	float scale=0.9f;	//畫布縮放比例
	float offsetX=0;   //按鈕X軸偏移量
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		if(state==1){
		mPaint.setColor(0xffcccccc);
		}else{
			mPaint.setColor(Color.GREEN);	
		}
        mPaint.setShadowLayer(0, 0, 0, Color.GRAY);  
		RectF mRectF=new RectF(0, 0, 100,50);
		canvas.drawRoundRect(mRectF, 50, 50, mPaint);
		mPaint.setColor(0xffffffff);
		canvas.save();
		canvas.scale(scale, scale, 50, 25);
		canvas.drawRoundRect(mRectF, 50, 50, mPaint);
		canvas.restore();
		if(state==1 && isAnim){
			scale-=0.1;
			offsetX+=5;
			invalidate();
			if(scale<=0.01){
				isAnim=false;
				state=0;
				scale=0.01f;
				offsetX=50;
				Log.i("test", "open");
			}
		}
		if(state==0 && isAnim){
			scale+=0.1;
			offsetX-=5;
			invalidate();
			if(scale>=0.9f){
				isAnim=false;
				state=1;
				scale=0.9f;
				offsetX=0;
				Log.i("test", "close");
			}
		}
		mPaint.setColor(0xffdddddd);
        mPaint.setShadowLayer(10, 0, 0, Color.GRAY);  
        canvas.save();
        canvas.translate(offsetX, 0);
		canvas.drawRoundRect(new RectF(1,1,48,48), 48, 48,mPaint);
		canvas.restore();
	}
}

4 最終效果


以上,便實現了一個簡單的 switchbutton,有些同學說,你好像沒有測量View啊,你這樣的話如果我設定了不同的寬高模式,會不會出現一些很奇怪的顯示效果呢?額,現在統一回復一下,這不是我們本篇文章的重點,關於View測量,大家可以看這篇來分別學習.http://blog.csdn.net/oxuanboy1/article/details/51148353