自定義View-自制簡單的鐘表
阿新 • • 發佈:2019-01-22
先上圖,效果大概就是這樣,秒針按秒走動,還有兩個齒輪不停的旋轉
這是一個自定義的View,齒輪是素材,其它的均為畫筆畫的。
大概的想法是:
1.繪製圓
2.繪製刻度與數字(採用畫布的旋轉進行繪製比較簡單)
3.繪製錶針(同樣採用畫布的旋轉實現)
4.繪製齒輪,並實現齒輪的轉動
5.齒輪的轉動採用屬性動畫,不停的旋轉,錶針的動畫是在一個執行緒中,每個1秒,使用postInvalidate() 繪製一遍畫布
下面上程式碼:
package com.example.animation; import java.util.Calendar; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.view.animation.LinearInterpolator; public class ClockView extends View{ private Bitmap gbitmap;//那個綠色齒輪 private Bitmap rbitmap;//那個紅色齒輪 private Matrix gmatrix;//綠色齒輪的Matrix private Matrix rmatrix;//紅色齒輪的Matrix 齒輪的轉動是根據Matrix的setRoate來進行改變的 private Paint paint; public ClockView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { paint = new Paint(); paint.setAntiAlias(true); gbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.g_gear); rbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.r_gear); gmatrix = new Matrix(); rmatrix = new Matrix(); run(); roate(); } public void run(){ new Thread(new Runnable() { @Override public void run() { while(true){ postInvalidate(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } //屬性動畫,是的齒輪旋轉 public void roate(){ final ValueAnimator vaAnimator = ValueAnimator.ofFloat(0,1.0f); vaAnimator.setDuration(3000); vaAnimator.setInterpolator(new LinearInterpolator()); vaAnimator.setRepeatCount(ValueAnimator.INFINITE); vaAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float degree = (Float) animation.getAnimatedValue()*360; gmatrix.setRotate(degree,gbitmap.getWidth()/2,gbitmap.getHeight()/2);//順時針轉動 rmatrix.setRotate(-degree,rbitmap.getWidth()/2,rbitmap.getHeight()/2);//逆時針轉動 postInvalidate(); } }); vaAnimator.start(); } @Override protected void onDraw(Canvas canvas) { gmatrix.postTranslate(getWidth()/2+80, getHeight()/2+160-gbitmap.getHeight()/2);//此處使用postTranslate,和setTranslate可以檢視一下 canvas.drawBitmap(gbitmap,gmatrix, null); rmatrix.postTranslate( getWidth()/2+80-gbitmap.getWidth()-rbitmap.getWidth()/2, getHeight()/2+160-rbitmap.getHeight()/2); canvas.drawBitmap(rbitmap,rmatrix,null); // 當前時間對應的角度 Calendar calendar = Calendar.getInstance(); float secRot = calendar.get(Calendar.SECOND) * 6; float minRot = calendar.get(Calendar.MINUTE) * 6 + 6 * secRot / 360F; float hrRot = (calendar.get(Calendar.HOUR_OF_DAY) % 12) * 30 + 30 * minRot / 360F; //繪製圓形錶盤 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5.0f); paint.setColor(Color.BLACK); canvas.drawCircle(getWidth()/2, getHeight()/2, getWidth()/2, paint); //繪製刻度 for(int i= 0;i<12;i++){ if(i==0||i==3||i==6||i==9){ paint.setStrokeWidth(5.f); paint.setTextSize(40); canvas.drawLine(getWidth()/2, getHeight()/2-getWidth()/2, getWidth()/2, getHeight()/2-getWidth()/2+60, paint); String number; if(i==0){ number = String.valueOf(12); }else{ number = String.valueOf(i); } canvas.drawText(number, getWidth()/2-paint.measureText(number)/2, getHeight()/2-getWidth()/2+90, paint); }else{ paint.setStrokeWidth(3.0f); paint.setTextSize(30); canvas.drawLine(getWidth()/2, getHeight()/2-getWidth()/2, getWidth()/2, getHeight()/2-getWidth()/2+60, paint); String number = String.valueOf( i); canvas.drawText(number, getWidth()/2-paint.measureText(number)/2, getHeight()/2-getWidth()/2+100, paint); } //通過使用旋轉畫布能更輕鬆的進行繪製 canvas.rotate(30,getWidth()/2,getHeight()/2); } //繪製中心圓圈 paint.setStyle(Paint.Style.FILL); canvas.drawCircle(getWidth()/2, getHeight()/2, 10, paint); //繪製錶針 paint.setColor(Color.BLACK); canvas.translate(getWidth()/2, getHeight()/2); paint.setStrokeWidth(15);//時針 canvas.rotate(hrRot-90, 0, 0);//旋轉繪製 canvas.drawLine(0, 0, 100, 0, paint); canvas.rotate(-(hrRot-90), 0, 0);//需要將旋轉的角度返回,進行下一個正確的繪製 paint.setStrokeWidth(10);//分針 canvas.rotate(minRot-90, 0, 0); canvas.drawLine(0, 0, 200, 0, paint); canvas.rotate(-(minRot-90),0,0); paint.setStrokeWidth(5); paint.setColor(Color.RED);//秒針 canvas.rotate(secRot-90,0,0); canvas.drawLine(0, 0, 230, 0, paint); canvas.rotate(-(secRot-90),0,0); } }
至於那兩個齒輪,我是在easyicon上找的,進去搜索齒輪就有...
佈局檔案:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.animation.ClockActivity" > <com.example.animation.ClockView android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
OK,有錯誤的地方請指出..