一起Talk Android吧(第四百一十八回:制作时钟)

news2025/7/18 2:28:08

文章目录

  • 整体思路
  • 准备画布
  • 绘制表盘
  • 绘制刻度
  • 绘制指针
  • 示例代码

各位看官们大家好,上一回中咱们说的例子是"解决Glide不能加载网络图片的方法",这一回咱们介绍的例子是"制作时钟"。闲话休提,言归正转,让我们一起Talk Android吧!

看官们,我们在前面章回中介绍了绘图相关的内容,本章回中将对这些知识做一个综合应用,以加深大家对绘图知识的理解。综合应用的例子是一个时钟,我们将介绍如何使用绘图知识来制作一个时钟。时钟的最终效果如下图所示:
在这里插入图片描述

整体思路

使用一块画布来绘制时钟,时钟是一个整体,不可能一次性全部把它全部绘制出来,因此把时钟拆分成小的模块,分模块来绘制。时钟可以拆分成表盘,表盘上的刻度和数字,指示时间的三个指针。我们将按分别绘制这些模块,最后将模块组成一个完整的时钟。

准备画布

我们自定义一个View并且重写View中的onDraw()方法,该方法的参数就是画布,我们将使用此画布来绘制时钟。

绘制表盘

时钟的表盘是圆形,我们在画布上画一个圆来表示表盘,画圆使用drawCircle()方法,圆心为画布的中心,半径使用自定义的数值,不过此值要小于画布的宽度,不然画布上无法显示完整的圆。

绘制刻度

时钟有60个刻度,而且刻度上还有数字。刻度就是一条直线,只是直线的长度和粗细需要自定义,这个通过设置画笔的属性就可以实现。

画直线使用drawLine()方法,起点是表盘,终点通过刻度的长度计算出来。刻度中有部分刻度为整小时,比如1,12等,这些刻度需要显示成数字,数字本质上是文字,使用drawText()方法就可以实现,不过要注意文字的长度和宽度会占用一部分空间。

刻度的起点位于表盘上,而且坐标都不同。我们使用旋转画布的思路,以表盘12点方向为刻度起点,每画一个刻度把画布旋转一个角度,角度值为60(360/60)这样保证了刻度的起点不变,变的是画布的角度。这个思路比较抽象,如果有看官不理解的话可以自己动手在纸上画画。按照此思路
来个循环,把60个刻度全部画出来,在画的过程中计算每个整点刻度,将整点刻度画成粗线或者数字。

绘制指针

指针一共三个,分别指示小时,分钟和秒。绘制指针的思路和绘制刻度的思路相同:旋转布画。不同点在于指针的起点是圆心,也就是时钟表盘的中央。每个指针的长度不同,这点通过计算得出,主要体现在终点的坐标上。每个指针的粗细也不同,通过配置画笔的属性来实现。

示例代码

下面是完成的示例代码,代码中添加了详细的注释,请大家参考:

    private void drawClockView(Canvas canvas) {
        //中心坐标,以View中心为表盘中心
        float oX = getWidth()/2;
        float oY = getHeight()/2;
        //刻度盘半径
        float r = 260;
        //刻度线的长度
        float scaleLen = 30;
        //刻度线之间的角度,一共60个刻度线,铺满一周为360度
        int angle = 360/60;

        //1.画表盘
        canvas.drawCircle(oX,oY,r,mArcPaint);

        canvas.save();
        //2.画刻度线
        //一共12个小时,每小时之间有5个空格,一共12*5个刻度线
        //从12点钟方向开始画刻度线,然后旋转画布,重复此过程直到最后一个刻度线
        //对于整点的刻度线加粗并且加长显示,或者显示为具体的数字,代码中用j表示
        for(int i=0,j=0; i<60; i++) {
            canvas.rotate(angle,oX,oY);
            if(i%5 == 0) {
                //从12点钟方向开始画,因此起点为(oX,oY-r+2)+2是圆的宽度,这样画出的刻度在圆内
//                canvas.drawLine(oX, oY - r+2, oX, oY - r + scaleLen+16, mTextBPaint);
                if( 0 == j){
                    //从12点钟方向开始画,因此起点为(oX,oY-r),-8和+24是数字的长宽,这样画出的刻度在圆内,可以自动计算数字的长宽
                    canvas.drawText(String.valueOf(12+j++), oX-8, oY - r + 24, mTextBPaint);
                }else {
                    canvas.drawText(String.valueOf(j++), oX-8, oY - r + 24, mTextBPaint);
                }
            }else {
                canvas.drawLine(oX,oY-r+2,oX,oY-r+scaleLen,mTextPaint);
            }
        }
        canvas.restore();

        //3.画小时、分钟、秒三个指针
        //获取当前的时间:小时、分钟、秒
        LocalDateTime nowTime = LocalDateTime.now();
        int hour = nowTime.getHour();
        int minute = nowTime.getMinute();
        int second = nowTime.getSecond();

        //画小时指针,每小时包含5个刻度,所以*5
        canvas.save();
        canvas.rotate(5*angle*(hour%12),oX,oY);
        canvas.drawLine(oX,oY,oX,oY-r/3,mHourPaint);
        canvas.restore();

        //画分钟指针
        canvas.save();
        canvas.rotate(angle*minute,oX,oY);
        canvas.drawLine(oX,oY,oX,oY-r*2/3,mMinutePaint);
        canvas.restore();

        //画秒指针
        canvas.save();
        canvas.rotate(angle*second,oX,oY);
        canvas.drawLine(oX,oY,oX,oY-r*5/6,mSecondPaint);
        canvas.restore();
    }

运行上面的代码就可以得到我们在开篇中演示的时钟。

看官们,关于Android中"绘图时钟"的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17539.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

向毕业妥协系列之深度学习笔记:神经网络深度学习(一)

目录 一.神经网络杂记 二.计算图&#xff08;反向传播求导几个实例&#xff09; 1.普通式子反向传播求导 2.逻辑回归中的梯度下降 3.m个样本的梯度下降 三.向量化 深度学习系列的文章也可以结合下面的笔记来看&#xff1a; 深度学习笔记-目录 一.神经网络杂记 这个系列…

不知道word压缩文件怎么弄?简单三步轻松实现

如果你是学生&#xff0c;那么你的作业、论文应该都是以word文档格式上交的吧&#xff1f; 如果你是打工人&#xff0c;应该也经常需要编辑一些文档&#xff0c;例如通知、工作安排等等&#xff0c;给上司或其他同事查阅。 那么久而久之积累下来&#xff0c;word文件就会占据电…

TIA博途_通过PEEK指令在TP900触摸屏上实现监控所有IO地址的具体方法示例

TIA博途_通过PEEK指令在TP900触摸屏上实现监控所有IO地址的具体方法示例 如下图所示,首先,新建一个项目,添加一个DB块,这里以DB276为例进行说明,在该DB块中添加如图所示变量, 如下图所示,添加一个FB,用于读取IO点的值,具体程序可参考下图, 如下图所示,在OB1中调…

使用马尔可夫链构建文本生成器

本文中将介绍一个流行的机器学习项目——文本生成器&#xff0c;你将了解如何构建文本生成器&#xff0c;并了解如何实现马尔可夫链以实现更快的预测模型。 文本生成器简介 文本生成在各个行业都很受欢迎&#xff0c;特别是在移动、应用和数据科学领域。甚至新闻界也使用文本生…

PyTorch中的matmul函数详解

PyTorch中的两个张量的乘法可以分为两种&#xff1a; 两个张量对应的元素相乘&#xff08;element-wise&#xff09;&#xff0c;在PyTorch中可以通过torch.mul函数&#xff08;或者∗*∗运算符&#xff09;实现 两个张量矩阵相乘&#xff08;Matrix product&#xff09;&…

Day07--生命周期的概念与分类

文字概述&#xff1a; 1.啥子是生命周期呢&#xff1f; ***********************************************************************************************************************************************************************************************************…

[附源码]Python计算机毕业设计毕业生就业信息管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

EasyExcel对大数据量表格操作导入导出

前言 最近有个项目里面中有大量的Excel文档导入导出需求&#xff0c;数据量最多的文档有上百万条数据&#xff0c;之前的导入导出都是用apache的POI&#xff0c;于是这次也决定使用POI&#xff0c;结果导入一个四十多万的文档就GG了&#xff0c;内存溢出... 于是找到EasyExce…

上采样,下采样,卷积,反卷积,池化,反池化,双线性插值【基本概念分析】

上采样,下采样,卷积,反卷积,池化,反池化,双线性插值【基本概念分析】】一、上采样1.概念2.原理二、下采样1.概念2.原理三、卷积与反卷积四、池化五、反池化六、双线性插值1.意义2.作用3.单线性插值4.双线性插值的公式5.双线性插值的例子一、上采样 1.概念 上采样&#xff08;…

前端页面全新的写法(第七课)Vue中的组件

VueCli框架的实操内容(第七课)Vue中的组件 组件是可复用的 Vue 实例, 把一些公共的模块抽取出来&#xff0c;然后写成单独的的工具组件或者页面&#xff0c;在需要的页面中就直接引入即可那么我们可以将其抽出为一个组件进行复用。例如 页面头部、侧边、内容区&#xff0c;尾部…

电脑里重要文件用什么备份,电脑如何备份主要数据

保护好数据安全是很重要的&#xff0c;能够给我们减少很多麻烦或者说是损失&#xff0c;所以&#xff0c;我们是有必要通过一些手段来保护好重要数据的。电脑里重要文件用什么备份&#xff1f;提前对数据进行备份无疑是最好的方法之一。 一、如何备份数据&#xff1f; 我们可以…

数据结构-排序算法总结

排序算法总结插入排序直接插入排序&#xff08;稳定&#xff09;希尔排序交换排序冒泡排序&#xff08;稳定&#xff09;快速排序选择排序简单选择排序堆排序归并排序&#xff08;稳定&#xff09;基数排序&#xff08;稳定&#xff09;多路归并排序&#xff08;外排序&#xf…

Stream之flatMap用法

记录一下flatMap的用法 个人理解是将流中的流合并 Data AllArgsConstructor NoArgsConstructor public class WhiteIp {//idprivate Integer id;//域名private String domain;//ip,多个用;分隔private String ipaddress;public static void main(String[] args) {WhiteIp w1 …

Android未捕获异常监控原理

背景 本文仅探讨java层的未捕获异常的监控为什么我们自己的异常捕获总是比 Bugly 收到的信息少&#xff1f; Android未捕获异常的监控与收集 Java层未捕获异常监控的基本实现 先看看Java层未捕获异常监控的运行过程&#xff1a; public class MyUncaughtExceptionHandler …

企业虚拟网络管理

随着企业规模的扩大&#xff0c;其网络的规模和复杂性也会成比例地扩展。企业级组织和中小型企业需要大规模网络来满足不断增长的业务需求。然而&#xff0c;大规模网络需要大量的物理组件、定期维护和配置&#xff0c;所有这些都是有代价的。因此&#xff0c;为了规避这些额外…

Spring Boot面试题

什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 开源组织下的子项目&#xff0c;其设计目的是专注于Spring应用的开发&#xff0c;开发人员可以把更多的精力放在业务代码上&#xff0c;而无需过多关注XML的配置&#xff0c;从而简化Spring应用开发&#xff0c;提高开发…

牛客小白月赛61-E

传送门 题意 给你一个长度为n的序列&#xff0c;它有n&#xff01;个排列方法 问在这n&#xff01;个排列方法中 逆序对的总数是多少 首先要知道 逆序对数n&#xff01;/2*&#xff08;不相等的数字对儿数&#xff09; 不相等的数组对儿数cn2c_{n}^{2}cn2​-Zcnum[a[i]2c_{n…

前端如何写进度条(上传或者下载文件的时候)

1.需求 在日常开发中&#xff0c;我们经常会遇到上传或者下载文件的需求&#xff0c;以下载为例&#xff1a; 如果后台文件是现成的&#xff0c;浏览器就会在底部出现下载的过程&#xff0c;如果点击下载后&#xff0c;有些业务是需要去打包&#xff0c;然后再下载文件的话&a…

【C++语法难点】 深拷贝和浅拷贝是什么,拷贝构造,拷贝赋值

文章目录1.开始&#xff1a;构造函数1.2 在栈区和堆区创建对象1.3 缺省构造函数1.4 类型转换构造函数1.5 拷贝构造函数1.6 缺省拷贝构造函数&#xff08;浅拷贝&#xff09;1.7 深拷贝构造函数 (深拷贝)1.8 拷贝赋值1.开始&#xff1a;构造函数 语法形式 class 类名{类名(形参…

UE5笔记【三】UE5材质Materials

材质&#xff1a;可以将材质看作是StaticMesh上面的绘画。这副绘画Paint是由图层组成的&#xff0c;这些图层形成了所谓的物理基础渲染&#xff08;Physically Based Rendering OR PBR&#xff09;。这些PBR的特殊之处在于&#xff1a;几乎可以让我们模拟显示世界中的任何材质。…