Android(安卓)自定义时钟控件
16lz
2022-05-27
1.创建ClockView
public class ClockView extends View {
public ClockView(Context context) { super(context); init(); } public ClockView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); }
}
2.初始化变量
//需要用到的画笔 private Paint mPaint, paintS, paintM, paintH, paintT; //控件宽高 private int width, height; //外圆边界 private RectF oval; //时针长度 private float hHeight = getResources().getDimension(R.dimen.x25); //分针长度 private float mHeight = getResources().getDimension(R.dimen.x30); //秒针长度 private float sHeight = getResources().getDimension(R.dimen.x40);
3.初始化画笔
private void init() { //外圆画笔 mPaint = new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); mPaint.setColor(Color.WHITE); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(getResources().getDimension(R.dimen.x2)); //时真画笔 paintH = new Paint(); paintH.setStyle(Paint.Style.STROKE); paintH.setAntiAlias(true); paintH.setColor(Color.WHITE); mPaint.setStrokeCap(Paint.Cap.ROUND); paintH.setStrokeWidth(getResources().getDimension(R.dimen.x8)); //分真画笔 paintM = new Paint(); paintM.setStyle(Paint.Style.STROKE); paintM.setAntiAlias(true); paintM.setColor(Color.WHITE); paintM.setStrokeWidth(getResources().getDimension(R.dimen.x4)); //秒真画笔 paintS = new Paint(); paintS.setStyle(Paint.Style.STROKE); paintS.setAntiAlias(true); paintS.setColor(Color.WHITE); paintS.setStrokeWidth(getResources().getDimension(R.dimen.x2)); //时间画笔 paintT = new Paint(); paintT.setColor(Color.WHITE); paintT.setStrokeWidth(getResources().getDimension(R.dimen.x1)); paintT.setTextSize(getResources().getDimension(R.dimen.x12)); }
4.绘制外圆弧
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); width = getWidth(); height = getHeight(); float x = (getWidth() - getHeight() / 2) / 2; float y = getHeight() / 4; oval = new RectF(x, y, width - x, height - y); //绘制外圆 canvas.drawArc(oval, 90, 270, false, mPaint); //绘制圆心 canvas.drawCircle(width / 2, height / 2, width / 60, mPaint); //绘制指针 int angles[] = getAngle(); drawLine(canvas, hHeight, paintH, angles[0]); drawLine(canvas, mHeight, paintM, angles[1]); drawLine(canvas, sHeight, paintS, angles[2]); makeText(canvas); }
这里绘制外部圆弧的方法五个参数 oval用于限定圆弧位置(作用等同于 left,top,right,bottom限定),90为起始角度(x轴正方向为0度), 第三个参数为结束角度,第四个参数为画笔
绘制圆心的方法1,2个参数为圆心坐标,第三个参数为圆半径,第四个参数为画笔
getAngle();以及drawLine();方法下面给出
5.获取时,分,秒指针的角度(12点方向为0度)
private int[] getAngle() { Date date = new Date(System.currentTimeMillis()); int hour = date.getHours(); int minuts = date.getMinutes(); int seconds = date.getSeconds(); if (hour >= 12) { hour = hour - 12; }
//时针角度 int h = 360 / 12 * hour;
//分针角度
int m = 360 / 60 * minuts;
//秒针角度
int s = 360 / 60 * seconds; return new int[]{h, m, s}; } 6.绘制指针
private void drawLine(Canvas canvas, float pHeight, Paint p, double angle) { //指针顶点起始位置
float x = width / 2; float y = height / 4 + (height / 4 - pHeight);
float roundWidth = width / 30; float xs = width / 2; float ys = height / 4 + (height / 4 - roundWidth); double hu = 0;
//1 hu = angle * Math.PI / 180;
//2 x = x + (float) (Math.sin(hu) * pHeight); xs = xs + (float) (Math.sin(hu) * roundWidth);
//3 y = y + (float) (pHeight - Math.cos(hu) * pHeight); ys = ys + (float) (roundWidth - Math.cos(hu) * roundWidth);
canvas.drawLine(xs, ys, x, y, p); }
这里传入的四个参数 canvas为画布,pHeight为指针长度,p为定义好的画笔,angle为指针当前的角度 1处:将角度转换为弧度制下面会用到 2处:计算 指针 起始x坐标 结束x坐标 3处:计算 指针 起始y坐标 结束y坐标
说下计算方法(此处是按照起始位置为圆心)
图1 图2 图1中 假设指针由a位置运动到b位置 图2中 画上辅助线 x为指针长度 A为旋转角度,由图可知 1顶点运动到2顶点,顶点在x轴上移动的距离为y的长度,顶点在y轴上移动的距离为 x-p 此时我们有x的长度 角A的大小 利用三角函数可得 y = x*sin(A); p = y*cos(A); (注意这里的A为弧度制 角度制转弧度制公式 rad = A*π/180) 知道了顶点在x,y轴上各移动了多少距离,知道初始位置计算现在的位置就非常简单了
canvas.drawLine(圆心,圆心, 起始顶点x坐标+x移动距离(y),起始顶点y坐标+y移动距离(x-p) , 画笔);
(如果对大于90,180有疑问可以自己研究下,不做赘述)
7.每秒钟绘制一次
这里我写了个timer来定时重绘 外部调用startClock就会发现秒针开始移动 private Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { invalidate(); return false; } }); public void startClock() { new Timer().schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(0); } }, 0, 1000); }
更多相关文章
- 关于android实现fastindexbar(快速索引)详解
- android刮刮乐
- Android上的OpenGL ES 使用错误 解决
- Android实时绘制效果(二)
- C基础—函数指针,联合体,枚举,结构体和结构体指针
- Android(安卓)自定义View——自定义View控件
- Android自定义实现圆形播放进度条
- Android的垃圾回收机制(android refbase类(sp wp))
- Android绘图之绘制太极图