1. 程式人生 > >通過Canvas的疊加實現Android中環形View的顏色填充動畫效果

通過Canvas的疊加實現Android中環形View的顏色填充動畫效果

最近看到很多國內和國外的APP很多表示資料的方式都是通過一個圓環和數字動態展現,很是生動啊,由此也想做個簡單的模型試一試效果!

在Android中實現一種效果的方式有很多種,本人使用繼承View類,通過Paint和Canvas繪圖疊加的方式實現。

首先新建一個RingView繼承View類,實現構造器函式如下:(同時獲取螢幕的寬和高)

      public RingView(Context context, AttributeSet attrs) {
		super(context, attrs);
		//獲取螢幕的寬,高
		WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
						
		width = wm.getDefaultDisplay().getWidth();
		height = wm.getDefaultDisplay().getHeight();
	}
接下來實現draw方法:

首先要繪製一個放在最底部的一個圓形,顏色設定為灰色:

@Override
	public void draw(Canvas canvas) {
 		// TODO Auto-generated method stub
		
		 //將圓心設定在螢幕中心
		int pointWidth = width / 2;
		 int pointHeight = height / 2;
		
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		 paint.setColor(Color.rgb(220, 220, 220));
		canvas.drawCircle(pointWidth, pointHeight, 100, paint);
	}


接下來需要在其上邊疊加一個畫弧的Canvas,顏色設定為紅色:

        @Override
	    public void draw(Canvas canvas) {
		 // TODO Auto-generated method stub
		
		...		
		 paint.setColor(Color.RED);
		 RectF f = new RectF(pointWidth - 100, pointHeight - 100, pointWidth + 100, pointHeight + 100);
		 canvas.drawArc(f, -90f, i, true, paint);
	   }

想要變成圓環狀,需要在其上邊再次繪製一個圓形,以遮擋住弧形,實現圓環狀的:顏色設定為白色

@Override
	public void draw(Canvas canvas) {
		// TODO Auto-generated method stub
		
		...		
 		paint.setColor(Color.WHITE);
		canvas.drawCircle(pointWidth, pointHeight, 80, paint);
	}

到目前為止,圓環狀已經出來了,但是我們的目的不是這樣就結束的,還要實現動態顯示和資料的關聯,所以需要在一個Activity中獲取資料並且更改第二層中Canvas繪製扇形的弧度大小,實現動態資料繫結。

在MainActivity中通過Handler方式提交invalidate()重繪介面,實現動態繪製View,首先在MainActivity中建立一個內部類CircleThread:

    private class CircleThread implements Runnable{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while(!Thread.currentThread().isInterrupted()){
				try {
					Thread.sleep(100);
					/**
					 * 在新的執行緒中,傳送訊息給View,更新介面資料
					 * 通過m++實現加速度方式的不斷加速繪製弧形
					 * i代表要繪製扇形的角度大小,預設下290度
					 */
					m++;
					Message msg = new Message();
					msg.what = 1;
					if(i < 290){
						i += m;
					}else{
						i = 290;
						return;
					}
					msg.obj = i;
					circleHandler.sendMessage(msg);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
    	
    }
傳送訊息給Handler,更新View介面
       private Handler circleHandler = new Handler(){
		
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(msg.what == 1){
				int temp = (Integer)msg.obj;
				ring.setI(temp);
				ring.invalidate();
			}
		};
	};
然後在onCreate方法中開啟新的執行緒,實現動態的效果
new Thread(new CircleThread()).start();
之後自己還實現了在EditText輸入框中輸入資料和繪製的弧形繫結,這部分具體程式碼就舍略了......

實現動態繪製環形之後,我們還需要知道環形所代表的數值大小。而不是一個大概的抽象的資料,所以我們需要在View的onDraw方法中實現顯示當前弧度的大小值:

@Override
	public void draw(Canvas canvas) {
		// TODO Auto-generated method stub
		
		...
		//繪製文字
		paint.setColor(Color.BLACK);
		//計算出數字的長度
		float lenTxt = paint.measureText(String.valueOf(i));
		canvas.drawText(String.valueOf(i), pointWidth - lenTxt / 2, pointHeight, paint);
		
	}
這樣基本就完成了最開始的設想,具體效果如下圖所示: