通過Canvas的疊加實現Android中環形View的顏色填充動畫效果
阿新 • • 發佈:2019-01-04
最近看到很多國內和國外的APP很多表示資料的方式都是通過一個圓環和數字動態展現,很是生動啊,由此也想做個簡單的模型試一試效果!
在Android中實現一種效果的方式有很多種,本人使用繼承View類,通過Paint和Canvas繪圖疊加的方式實現。
首先新建一個RingView繼承View類,實現構造器函式如下:(同時獲取螢幕的寬和高)
接下來實現draw方法: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(); }
首先要繪製一個放在最底部的一個圓形,顏色設定為灰色:
@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);
}
這樣基本就完成了最開始的設想,具體效果如下圖所示: