Android初级进阶之自定义时钟(一)

简介: 前言一直以为仪表盘,时钟之类的非常的难,不敢去触摸这个领域。真正接触了才发现不过如此。技术要点1. cancvas 1. Cancvas.

前言

一直以为仪表盘,时钟之类的非常的难,不敢去触摸这个领域。真正接触了才发现不过如此。

技术要点

1. cancvas
        1. Cancvas.save()        保存画布
        2. Cancvas.restore()    合并画布
        3. Cancvas.translate()    切换x,y坐标点
        4. Cancvas.rotate()        旋转画布
2. 自定义View相关的知识
    1. Measure

目标

实现静态的时钟UI

效果图

img_f6495c91c1d725e70e782cfc8431b084.png
1.测量

测量View的宽度与高度,因为是画一个圆形的时钟,所以View取得是高度与宽度的最小值,一下是测量方法

``` java
private int measureSize(int spec) {
    int result;
    int size = MeasureSpec.getSize(spec);//获取大小
    int mode = MeasureSpec.getMode(spec);//获取模式
    if (mode == MeasureSpec.EXACTLY) {
        result = size;
    } else {
        result = 100;
        if (mode == MeasureSpec.AT_MOST) {
            result = Math.min(result, size);
        }
    }
    return result;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    mCircleWidth = Math.min(measureSize(heightMeasureSpec), measureSize(widthMeasureSpec));
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

``` 
2.绘制最外层的圆
``` java
//外部圆
Paint paintCircle = new Paint();
paintCircle.setStyle(Paint.Style.STROKE);//圆环
paintCircle.setAntiAlias(true);//抗锯齿
paintCircle.setStrokeWidth(5);//圆环宽度
canvas.drawCircle(mCircleWidth / 2, mCircleWidth / 2, mCircleWidth / 2 - 20/*减去20的原因是中心点留白*/, paintCircle);
``` 
img_0a95cbe388d30c5f2b7a1ed595cf3d5a.png
3.绘制刻度线与刻度值

绘制刻度线与刻度值是最大的难点,在这里就是利用了Canvas为我们提供的rotate方法,顾名思义,就是旋转画布。我们以视图坐标系 x y 进行绘制,没绘制完成一次,旋转相应的角度就完成了刻度线的绘制。玩过PS的人应该好理解。

``` java
//刻度线
Paint paintDegree = new Paint();
paintDegree.setStrokeWidth(3);
for (int i = 0; i < 60; i++) {
    if (i % 5 == 0) {
        paintDegree.setStrokeWidth(5);// 小时
        paintDegree.setTextSize(30);
        canvas.drawLine(mCircleWidth / 2, 20/*绘制外圆减去的值*/, mCircleWidth / 2, 60/*刻度线的长度*/, paintDegree);
        String degree = "12";
        if (i != 0)
            degree = String.valueOf(i / 5);
        canvas.drawText(degree, mCircleWidth / 2 - paintDegree.measureText(degree) / 2, 90/*字体的高度*/, paintDegree);
    } else {
        paintDegree.setStrokeWidth(3);//秒
        paintDegree.setTextSize(15);
        canvas.drawLine(mCircleWidth / 2, 20/*绘制外圆减去的值*/, mCircleWidth / 2, 30/*刻度线的长度*/, paintDegree);
        String degree = String.valueOf(i);
        canvas.drawText(degree, mCircleWidth / 2 - paintDegree.measureText(degree) / 2, 60/*字体的高度*/, paintDegree);
    }
    // 旋转六度,360度/60秒  以时钟的中心点进行旋转
    canvas.rotate(6, mCircleWidth / 2, mCircleWidth / 2);
}
``` 
img_ea5b8c9131c38565d347d8eea13d388a.png
4. 绘制时分秒指针
``` java
//画针
Paint paintHour = new Paint();
paintHour.setStrokeWidth(20);
Paint paintMinute = new Paint();
paintMinute.setStrokeWidth(10);
Paint paintSecond = new Paint();
paintSecond.setStrokeWidth(7);
canvas.save();
// 将 x y 点移到 中心
canvas.translate(mCircleWidth / 2, mCircleWidth / 2);
//float startX, float startY, float stopX, float stopY
canvas.drawLine(0, 0, 100, 100/*暂时写死*/, paintHour);
canvas.drawLine(0, 0, 100, 280, paintSecond);
canvas.drawLine(0, 0, 100, 200, paintMinute);
//合并 画布
canvas.restore();
```
img_f6495c91c1d725e70e782cfc8431b084.png
PS

Android初级进阶之自定义时钟(一)就到这里结束,原谅我的文学水平,没有过多的文字修饰。

Android初级进阶之自定义时钟(二)

1. 完成时分秒指针的计算。
2. 与系统时间进行同步,完成真正的时钟。
目录
相关文章
|
23天前
|
XML IDE 开发工具
【Android UI】自定义带按钮的标题栏
【Android UI】自定义带按钮的标题栏
30 7
【Android UI】自定义带按钮的标题栏
|
10天前
|
搜索推荐 数据库 Android开发
自定义头像 Android
【6月更文挑战第16天】
|
23天前
|
XML API Android开发
android上FragmentTabHost实现自定义Tab Indicator
android上FragmentTabHost实现自定义Tab Indicator
20 1
|
23天前
|
XML 前端开发 API
Android中实现Bitmap在自定义View中的放大与拖动
Android中实现Bitmap在自定义View中的放大与拖动
61 1
|
2天前
|
Android开发
Android自定义View之正方形
【6月更文挑战第23天】
|
3天前
|
搜索推荐 Android开发 开发者
Android 自定义组件
Android 自定义组件
6 0
|
9天前
|
存储 算法 Java
Android 进阶——代码插桩必知必会&ASM7字节码操作
Android 进阶——代码插桩必知必会&ASM7字节码操作
32 0
|
9天前
|
开发工具 Android开发
Android 代码自定义drawble文件实现View圆角背景
Android 代码自定义drawble文件实现View圆角背景
15 0
|
9天前
|
Android开发
Android 自定义View 测量控件宽高、自定义viewgroup测量
Android 自定义View 测量控件宽高、自定义viewgroup测量
14 0
|
9天前
|
开发工具 Android开发 git
Android自定义View——可以设置最大宽高的FrameLayout
Android自定义View——可以设置最大宽高的FrameLayout
21 0