自訂群組件-繪製時鐘,組件繪製時鐘
1、
2、Canvas對象詳解
1.translate(x,y):平移,將畫布的座標原點向左右方向移動x,向上下方向移動y.canvas的預設位置是在(0,0).
例子:畫布原點假如落在(1,1),那麼translate(10,10)就是在原點(1,1)基礎上分別在x軸、y軸移動10,則原點變為(11,11)。
2.scale(x,y):擴大。x為水平方向的放大倍數,y為豎直方向的放大倍數。
3.rotate(angel):旋轉.angle指旋轉的角度,順時針旋轉。
4.transform():切變。所謂切變,其實就是把映像的頂部或底部推到一邊。5 save:用來儲存Canvas的狀態。save之後,可以調用Canvas的平移、放縮、旋轉、錯切、裁剪等操作。
6 restore:用來恢複Canvas之前儲存的狀態。防止save後對Canvas執行的操作對後續的繪製有影響。save和restore要配對使用(restore可以比save少,但不能多),如果restore調用次數比save多,會引發Error。
7、drawTextOnPath 在指定的path上面繪製文字。3、代碼
package com.example.canvastest.view;import java.util.Calendar;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Align;import android.graphics.Paint.Style;import android.graphics.Path;import android.graphics.RectF;import android.os.Handler;import android.util.AttributeSet;import android.util.Log;import android.view.View;import com.example.canvastest.DensityUtil;import com.example.canvastest.R;/** * 繪製時鐘 * * @author libin * */public class ClockView extends View {// 半徑private float radius = 200;private Paint mDownPaint;// 寬度private float mCirclePaintWidth = 10; // 上面圓圈的畫筆private Paint mOutSidePaint;// 畫文字private Paint mTextPaint;// 文字大小private int textFontSize = 16;private int longLine ;private int shortLine;private int widthLine ;//小圓心的半徑private int circle;private int hourDegrees;private int minDegrees;private int secDegrees; public ClockView(Context context) {super(context);init();}public ClockView(Context context, AttributeSet attrs) {super(context, attrs);init();}public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {mDownPaint = new Paint();mDownPaint.setColor(Color.BLACK);mDownPaint.setAntiAlias(true);mDownPaint.setStrokeWidth(mCirclePaintWidth);textFontSize = (int) getResources().getDimension(R.dimen.textSize);shortLine = (int) getResources().getDimension(R.dimen.shortLine);longLine = (int) getResources().getDimension(R.dimen.longLine);widthLine = (int) getResources().getDimension(R.dimen.widthLine);radius = (int) getResources().getDimension(R.dimen.circleRadius);circle = (int) getResources().getDimension(R.dimen.circle);// 上面的畫筆mOutSidePaint = new Paint();mOutSidePaint.setAntiAlias(true);mOutSidePaint.setStrokeWidth(mCirclePaintWidth);mOutSidePaint.setStyle(Style.STROKE);mOutSidePaint.setColor(Color.BLACK);// 上面的畫筆mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setColor(Color.BLACK);mTextPaint.setStrokeWidth(widthLine);mTextPaint.setTextAlign(Align.CENTER);mTextPaint.setTextSize(textFontSize);mDownPaint.setTextSize(textFontSize);mHandler.sendEmptyMessage(10);}@Overrideprotected void onDraw(Canvas canvas) {// 平移,將畫布的座標原點向左右方向移動x,向上下方向移動y.canvas的預設位置是在(0,0).// 例子:畫布原點假如落在(1,1),那麼translate(10,10)就是在原點// (1,1)基礎上分別在x軸、y軸移動10,則原點變為(11,11)。canvas.translate(canvas.getWidth() / 2, canvas.getHeight() / 2); // 將位置移動畫紙的座標點:150,150// 畫圓canvas.drawCircle(0, 0, radius, mOutSidePaint);canvas.save();// 繪製路徑Path path = new Path();path.addArc(new RectF(-radius, -radius, radius, radius), -180, 180);mDownPaint.setTextAlign(Align.CENTER);int pathy = DensityUtil.dip2px(getContext(), -5);// 讓文字顯示到中間canvas.drawTextOnPath("canvas繪製鐘錶", path, 0, pathy, mDownPaint);canvas.restore();//繪製刻度canvas.save();canvas.rotate(210);float y = radius;int count = 60; // 總刻度數for (int i = 0; i < count; i++) {if (i % 5 == 0) {canvas.drawLine(0f, y-longLine+2, 0, y+mCirclePaintWidth/2 , mTextPaint);canvas.drawText(String.valueOf(i / 5 + 1), 0, y -mCirclePaintWidth/2-longLine, mTextPaint);} else {canvas.drawLine(0f, y - shortLine , 0f,y-mCirclePaintWidth/2, mTextPaint);}canvas.rotate(360 / count, 0f, 0f); // 旋轉畫紙}canvas.restore(); //繪製秒針canvas.save();canvas.rotate(secDegrees);Paint hourPaint = new Paint(mDownPaint);hourPaint.setColor(Color.BLACK);hourPaint.setStrokeWidth(circle); canvas.drawLine(0, -longLine, 0, radius*2/3, hourPaint);canvas.restore();//繪製分針canvas.save();canvas.rotate(minDegrees);canvas.drawLine(0, -longLine, 0, radius*1/2, hourPaint);canvas.restore();//繪製時針canvas.save();canvas.rotate(hourDegrees);canvas.drawLine(0, -longLine, 0, radius*1/3, hourPaint);canvas.restore();//繪製中心黑點Paint tmpPaint = new Paint(mDownPaint);tmpPaint.setColor(Color.BLACK);canvas.drawCircle(0, 0, circle*2, tmpPaint); //繪製中心紅點tmpPaint.setColor(Color.RED);canvas.drawCircle(0, 0, circle*4/3, tmpPaint);super.onDraw(canvas);} /** * 擷取角度 */private void calculate(){Calendar calendar = Calendar.getInstance();int hour = calendar.get(Calendar.HOUR);if (hour>12) {hour = hour-12;}hourDegrees = hour*30-180;int min = calendar.get(Calendar.MINUTE);minDegrees = min * 6-180;int sec = calendar.get(Calendar.SECOND);secDegrees = sec * 6-180;Log.i("tag", " "+ hour+" "+min+" "+sec);}/** * 定時器 */private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case 10:calculate();invalidate();this.sendEmptyMessageDelayed(10, 1000);break;default:break;}};};}4、常量資料
<dimen name="textSize">14sp</dimen> <dimen name="circleRadius">100dip</dimen> <dimen name="shortLine">9dip</dimen> <dimen name="longLine">15dip</dimen> <dimen name="widthLine">5dip</dimen> <dimen name="circle">3dip</dimen>