怎样帮别人做网站,企业形象广告设计,网站建设教程 作业,wordpress主题小图标项目目录 一、项目概述二、开发环境三、详细设计3.1、尺寸设置3.2、绘制表盘和指针3.3、动态效果 四、运行演示五、总结展望六、源码获取 一、项目概述
在安卓开发中#xff0c;当系统自带的View已经无法满足项目需求时#xff0c;就要自定义View。在Android中是没有与钟表有… 项目目录 一、项目概述二、开发环境三、详细设计3.1、尺寸设置3.2、绘制表盘和指针3.3、动态效果 四、运行演示五、总结展望六、源码获取 一、项目概述
在安卓开发中当系统自带的View已经无法满足项目需求时就要自定义View。在Android中是没有与钟表有关的View因此我们制作一个简单的钟表View这样就可以在其他项目中进行使用。
自定义钟表具有表盘表盘上有12个刻度有时针、分针、秒针和家里面的石英表样式相同用于显示时间会比数码表更加有内涵。
二、开发环境
只要是21年之后从Android Studio官网下载的AS都可以运行该App。因为高版本IDE向下兼容只需要修改Java环境。 三、详细设计
3.1、尺寸设置
onMeasure方法被重写用于决定自定义View的最终大小。这个过程考虑了父布局传递过来的宽度和高度的具体规格spec。MeasureSpec类提供了一种方式来理解这些规格包括它们的模式和大小。
模式有三种
UNSPECIFIED父布局没有限制子View的大小子View可以选择任何大小。EXACTLY父布局指定了一个确切的大小子View应该尽可能地匹配这个大小。AT_MOST父Layout设定了一个最大值子View的大小不能超过这个值。
在代码中首先检查了宽度和高度的规格模式。
如果宽度和高度都是EXACTLY则取两者中的较小值作为View的大小。如果只有高度是EXACTLY则取高度的值作为View的大小。如果只有宽度是EXACTLY则取宽度的值作为View的大小。如果两者都不是EXACTLY则取一个默认的值400作为View的大小。
最后调用setMeasuredDimension(int, int)方法来设置View的大小。这个方法接受两个参数第一个是View的宽度第二个是View的高度。由于在本例中View是一个圆形所以不管宽度还是高度最终的大小都会被设置为相同的值从而保证View是完美圆形的。
这种方法确保了View在不同设备和屏幕方向上具有一致的外观和大小前提是父布局至少为View指定了一个方向上的确切大小。如果宽度和高度都没有具体的规格那么View将会有一个默认的400px大小。这可能会导致View在布局中超出预期的范围因此在实际应用中可能需要对这种情况进行额外的处理。 //显示的尺寸和使用时传入的宽高相关因为整体为圆形Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//获取传入宽高的模式int wmode MeasureSpec.getMode(widthMeasureSpec);int hmode MeasureSpec.getMode(heightMeasureSpec);int wsize MeasureSpec.getSize(widthMeasureSpec);int hsize MeasureSpec.getSize(heightMeasureSpec);//判断模式获取最终显示的尺寸int size 400;if (wmode MeasureSpec.EXACTLY) {if (hmode MeasureSpec.EXACTLY) {size Math.min(wsize, hsize);} else {size wsize;}} else {if (hmode MeasureSpec.EXACTLY) {size hsize;} else {size 400;}}//将测量好的值设置给宽高setMeasuredDimension(size, size);}3.2、绘制表盘和指针
重写onDraw方法来绘制时钟的表盘和指针。在绘制之前先创建一个Paint对象并根据需要设置其样式、颜色、宽度等属性。设置Paint对象的抗锯齿模式为true这样可以让时钟的数字和指针看起来更加平滑。 Paint paint new Paint();//设置抗锯齿paint.setAntiAlias(true);//获取在布局当中设置的自定义属性设置给viewTypedArray typedArray context.obtainStyledAttributes(attrs, R.styleable.ColokView);int color typedArray.getColor(R.styleable.ColokView_clockColor, Color.BLACK);//设置画笔的颜色paint.setColor(color);时钟想要显示当前时间所以必须获取系统的准确时间并将其分解为小时、分钟和秒。定义一个getTime方法获取系统时间。首先创建了一个 Calendar 类的实例通过调用静态方法 getInstance() 来初始化该实例这样可以确保 calendar 对象包含了调用该方法时设备上的当前日期和时间。
接下来使用 calendar 对象来获取当前的时间
hours calendar.get(Calendar.HOUR); 这行代码获取了当前的小时数但是请注意这是基于12小时制的所以它返回的小时数范围是0午夜12点到11中午12点。minutes calendar.get(Calendar.MINUTE); 这行代码获取了当前的分钟数范围是0到59。seconds calendar.get(Calendar.SECOND); 这行代码获取了当前的秒数范围也是0到59。 //获取当前时间的方法public void getTime() {Calendar calendar Calendar.getInstance();hours calendar.get(Calendar.HOUR);minutes calendar.get(Calendar.MINUTE);seconds calendar.get(Calendar.SECOND);}下面讲解onDraw方法的具体实现它负责在View上绘制表盘和指针。
首先覆盖了onDraw方法这个方法是View类的一部分用于在View上进行绘制。调用super.onDraw(canvas);确保父类的绘制逻辑得到执行。设置画笔的风格为空心STROKE这样绘制的图形只有边缘有颜色。设置View的内边距为20像素。绘制外层大圈设置线条宽度为8像素以View中心为圆心以View宽度的一半减去20像素为半径绘制一个圆。绘制内层大圆设置线条宽度为4像素以View中心为圆心以View宽度的一半减去30像素为半径绘制一个圆。绘制时钟的中心点小圆设置填充样式为FILL以View中心为圆心以10像素为半径绘制一个圆。循环12次绘制时钟的12个刻度。每次循环中 保存当前的Canvas状态。使用canvas.rotate()方法根据角度绘制刻度这里有一个问题因为每次旋转后都应该绘制新的刻度但代码中却重复绘制了相同的刻度这可能是一个错误。发送一个空消息延迟1秒通过handler.sendEmptyMessageDelayed(1, 1000);这部分代码的意图可能是让时钟每秒移动一次但它被放置在了绘制刻度的循环中这也是一个逻辑错误。 绘制时针 设置画笔宽度为8像素。保存Canvas状态。根据当前小时数和分钟数计算出的角度旋转Canvas。绘制时针从View中心向上40像素处开始到60像素处结束。恢复Canvas状态。 绘制分针 设置画笔宽度为5像素。保存Canvas状态。根据当前分钟数计算出的角度旋转Canvas。绘制分针从View中心向上2/3的高度处开始向下2/3的高度处结束。恢复Canvas状态。 绘制秒针与上述分针的逻辑基本相同只是画笔宽度改为3像素角度计算改为每秒钟6度。 //显示的内容就在onDraw方法中进行绘制Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//设置空心paint.setStyle(Paint.Style.STROKE);//设置内边距setPadding(20, 20, 20, 20);//绘制外层大圈paint.setStrokeWidth(8);//设置线条宽度canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - 20, paint);//绘制内层大圆paint.setStrokeWidth(4);canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - 30, paint);//绘制表中间轴心paint.setStyle(Paint.Style.FILL);canvas.drawCircle(getWidth() / 2, getHeight() / 2, 10, paint);//绘制表的刻度12个通过旋转画布实现for (int i 1; i 12; i) {//保存画布的状态canvas.save();//旋转到指定的角度canvas.rotate(30 * i, getWidth() / 2, getHeight() / 2);canvas.drawLine(getWidth() / 2, 40, getWidth() / 2, 60, paint);//恢复旋转之前的状态canvas.restore();handler.sendEmptyMessageDelayed(1, 1000);}//绘制时针,1h30°,1m0.5°paint.setStrokeWidth(8);canvas.save();//旋转画布旋转的度数由当前时间决定canvas.rotate(30 * hours 0.5f * minutes, getWidth() / 2, getHeight() / 2);canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getHeight() / 5, paint);canvas.restore();//绘制分针,1min6°paint.setStrokeWidth(5);canvas.save();canvas.rotate(6 * minutes, getWidth() / 2, getHeight() / 2);canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getHeight() / 4, paint);canvas.restore();//绘制秒针,1s6°paint.setStrokeWidth(3);canvas.save();canvas.rotate(6 * seconds, getWidth() / 2, getHeight() / 2);canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2 - getHeight() / 3, paint);canvas.restore();}
3.3、动态效果
为了让指针走起来我们定义了一个Handler的匿名子类并覆写了其handleMessage方法。Handler通常用于处理线程间通信特别是在Android开发中它常用来处理UI线程主线程和后台线程之间的消息传递。
在handleMessage方法中首先检查传入的Message对象的what字段是否等于1。如果是表示该消息需要被处理 调用getTime()方法来获取当前的时间。 调用invalidate()方法强制重新绘制View。invalidate()方法会告诉系统该View的部分或全部区域已经变得不再有效需要重绘。调用此方法后系统将安排onDraw方法在适当的时候被再次调用。 使用handler.sendEmptyMessageDelayed(1, 1000);来设定一个定时器。这行代码的意思是它会让当前的消息处理器handler在1000毫秒即1秒后再次向自己发送一个what值为1的空Message对象。这样就创建了一个每秒重复执行一次的循环用于不断更新时钟时间并刷新界面。
通过Handler在Android的主线程上每秒更新并重绘时钟界面从而模拟了一个动态的时钟效果。 Handler handler new Handler() {Overridepublic void handleMessage(NonNull Message msg) {super.handleMessage(msg);if (msg.what 1) {//重新获取时间getTime();//重新绘制界面invalidate();handler.sendEmptyMessageDelayed(1, 1000);}}};四、运行演示 五、总结展望
总的来说本次自定义钟表项目可以学习到编程技巧并且加深对Canvas API的理解。大家可以考虑添加一些定制选项如不同的表盘样式、颜色或字体以便用户可以根据自己的喜好来个性化他们的时钟也可以考虑添加一些高级功能如秒表、闹钟或世界时钟以扩展应用程序的实用性。简单的项目掌握透了就不简单期待大家在此基础上制作更多的创新钟表
六、源码获取
♻️下面两种方式都可以获取源代码1️⃣ 点击直接下载 Android Studio 自定义钟表2️⃣关注公众号《 萌新加油站 》后台回复 钟表 这有你错过的精彩内容Android Studio实现文艺阅读App Android Studio实现志愿者系统Android Studio实现多功能日记本Android Studio实现推箱子小游戏Android Studio实现五子棋小游戏 普劝青年烈士黄卷名流发觉悟之心破色魔之障。芙蓉白面须知带肉骷髅。美貌红妆不过蒙衣漏厕。纵对如玉如花之貌皆存若姊若母之心。未犯淫邪者宜防失足。曾行恶事者务劝回头。更祈展转流通迭相化导。必使在在齐归觉路人人共出迷津。——《欲海回狂》