前言

本篇文章主要介绍使用自定义 View 来实现时钟效果,灵活地使用 Android 的 CanvasPaint, Path 的 API 以及理清 Canvassaverestore 的意义。

代码实现

1. 新建一个类继承 View

public class ClockView extends View {//原点private Point mCoo = new Point(500, 800);private Path mMainPath;private Paint mMainPaint;public ClockView(Context context) {this(context,null);}public ClockView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}private void init() {//初始化画笔mMainPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mMainPaint.setStyle(Paint.Style.STROKE);mMainPaint.setStrokeCap(Paint.Cap.ROUND);mMainPath = new Path();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制canvas.save();//新建图层1canvas.translate(mCoo.x, mCoo.y);drawBreakCircle(canvas);drawDot(canvas);drawText(canvas);Calendar calendar = Calendar.getInstance();int hour = calendar.get(Calendar.HOUR_OF_DAY);int min = calendar.get(Calendar.MINUTE);int sec = calendar.get(Calendar.SECOND);drawH(canvas, hour / 12.f * 360 - 90 + min / 60.f * 30 + sec / 3600.f * 30);drawM(canvas, min / 60.f * 360 - 90 + sec / 60.f);drawS(canvas, sec / 60.f * 360 - 90);canvas.restore();}}

2. 绘制逻辑

2.1 绘制破碎的圆

 /*** 绘制破碎的圆** @param canvas*/private void drawBreakCircle(Canvas canvas) {mMainPaint.setStrokeWidth(8);mMainPaint.setColor(Color.parseColor("#D5D5D5"));for (int i = 0; i < 4; i++) {canvas.save();canvas.rotate(90 * i);canvas.drawArc(-350, -350, 350, 350,10, 70, false, mMainPaint);canvas.restore();}}

2.2 绘制小点
画 60 个点(小线),每逢 5 变长,也就是画直线,每次将画布旋转 360 / 60 = 6°

 /*** 绘制小点** @param canvas*/private void drawDot(Canvas canvas) {for (int i = 0; i < 60; i++) {if (i % 5 == 0) {canvas.save();canvas.rotate(30 * i);mMainPaint.setStrokeWidth(8);mMainPaint.setColor(randomRGB());canvas.drawLine(250, 0, 300, 0, mMainPaint);mMainPaint.setStrokeWidth(10);mMainPaint.setColor(Color.BLACK);canvas.drawPoint(250, 0, mMainPaint);canvas.restore();} else {canvas.save();canvas.rotate(6 * i);mMainPaint.setStrokeWidth(4);mMainPaint.setColor(Color.BLUE);canvas.drawLine(280, 0, 300, 0, mMainPaint);canvas.restore();}}}
 /*** 返回随机颜色** @return 随机颜色*/public static int randomRGB() {Random random = new Random();int r = 30 + random.nextInt(200);int g = 30 + random.nextInt(200);int b = 30 + random.nextInt(200);return Color.rgb( r, g, b);}

2.3 绘制文字

/*** 添加文字** @param canvas*/private void drawText(Canvas canvas) {mMainPaint.setTextSize(60);mMainPaint.setStrokeWidth(5);mMainPaint.setStyle(Paint.Style.FILL);mMainPaint.setTextAlign(Paint.Align.CENTER);mMainPaint.setColor(Color.BLUE);canvas.drawText("Ⅲ", 350, 30, mMainPaint);canvas.drawText("Ⅵ", 0, 350 + 30, mMainPaint);canvas.drawText("Ⅸ", -350, 30, mMainPaint);canvas.drawText("Ⅻ", 0, -350 + 30, mMainPaint);//使用外置字体放在assets目录下Typeface myFont = Typeface.createFromAsset(getContext().getAssets(), "CHOPS.TTF");mMainPaint.setTypeface(myFont);mMainPaint.setTextSize(70);canvas.drawText("Kevin", 0, -150, mMainPaint);}

tips:
.ttf 字体文件下载地址:https://www.fonts.net.cn/

2.4 绘制时针

 /*** 绘制时针** @param canvas* @param deg*/private void drawH(Canvas canvas, float deg) {canvas.save();canvas.rotate(deg);mMainPaint.setColor(Color.BLACK);mMainPaint.setStrokeCap(Paint.Cap.ROUND);mMainPaint.setStrokeWidth(8);canvas.drawLine(0, 0, 150, 0, mMainPaint);canvas.restore();}

2.5 绘制分针

 /*** 绘制分针** @param canvas* @param deg*/private void drawM(Canvas canvas, float deg) {canvas.save();canvas.rotate(deg);mMainPaint.setColor(Color.BLACK);mMainPaint.setStrokeWidth(8);canvas.drawLine(0, 0, 200, 0, mMainPaint);mMainPaint.setColor(Color.GRAY);mMainPaint.setStrokeWidth(30);canvas.drawPoint(0, 0, mMainPaint);canvas.restore();}

2.6 绘制秒针

 /*** 绘制秒针** @param canvas* @param deg*/private void drawS(Canvas canvas, float deg) {mMainPaint.setStyle(Paint.Style.STROKE);mMainPaint.setColor(Color.RED);mMainPaint.setStrokeWidth(8);mMainPaint.setStrokeCap(Paint.Cap.SQUARE);canvas.save();canvas.rotate(deg);canvas.save();canvas.rotate(45);//使用path绘制:在init里初始化一下就行了mMainPath.addArc(-25, -25, 25, 25, 0, 240);canvas.drawPath(mMainPath, mMainPaint);canvas.restore();mMainPaint.setStrokeCap(Paint.Cap.ROUND);canvas.drawLine(-25, 0, -50, 0, mMainPaint);mMainPaint.setStrokeWidth(2);mMainPaint.setColor(Color.RED);canvas.drawLine(0, 0, 320, 0, mMainPaint);mMainPaint.setStrokeWidth(15);mMainPaint.setColor(Color.RED);canvas.drawPoint(0, 0, mMainPaint);canvas.restore();}

让时钟动起来

1. 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/white"android:orientation="vertical"tools:context=".ParcticeOneActivity"><com.kjd.gesturedemo.widget.ClockViewandroid:id="@+id/clockView"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

2. 更新时间

public class ParcticeOneActivity extends AppCompatActivity {/*** 新建Handler*/Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {mView.invalidate();//处理:刷新视图}};private View mView;private final Timer timer = new Timer();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_parctice_one);mView = findViewById(R.id.clockView);TimerTask timerTask = new TimerTask() {@Overridepublic void run() {mHandler.sendEmptyMessage(0);//发送消息}};//定时任务timer.schedule(timerTask, 0, 1000);}public void clicked(View view) {new HighLightView(this).showTipForView(view, "", new View.OnClickListener() {@Overridepublic void onClick(View v) {}});}
}

【Android 自定义 View】--> 绘制时钟(表)效果相关推荐

  1. android 立体 流量球,Android自定义View——实现水波纹效果类似剩余流量球

    Android自定义View--实现水波纹效果类似剩余流量球 三个点   pre   ber   block   span   初始化   move   理解最近突然手痒就想搞个贝塞尔曲线做个水波纹效 ...

  2. android自定义弧度按钮,Android 自定义View 绘制六边形设置按钮

    今天逛酷安的时候,发现酷安的设置按钮(截图的右上角),是一个六边形 + 中心圆的图标,所以又是一个自定义View练习对象了.画圆很简单,知道半径即可,而重点就在画出六边形. 酷安截图.png 最终效果 ...

  3. Android自定义View绘制闹钟

    Android自定义View绘制闹钟 本文简单实现了一个闹钟,扩展View,Canvas绘制 效果如下: 代码如下: package com.gaofeng.mobile.clock_demo;imp ...

  4. Android 自定义View绘制电池图标

    /*** @anthor GrainRain* @funcation 自定义View绘制电池* @date 2019/8/27*/ public class DrawBatteryView exten ...

  5. Android自定义View绘制流程

    Android视图层次结构简介 在介绍View绘制流程之前,咱们先简单介绍一下Android视图层次结构以及DecorView,因为View的绘制流程的入口和DecorView有着密切的联系. 我们平 ...

  6. android 自定义View绘制电池电量(电池内带数字显示)

    最新公司需要一个电池内带数字的显示电池电量需求,百度了一下.参考下面这篇文章写的Android自定义View之电池电量显示. 增加了里面电池电量数字显示,还有就是一个屏幕适配.不管屏幕分辨率基本都能适 ...

  7. android 环绕布局,Android自定义View实现圆形环绕效果

    之前项目中需要实现一个四周环绕中心圆形头像的效果,感觉还是自定义比较方便,于是就自己封装了一个控件去实现.先贴张图显示最终效果. 首先自定义一个View继承自LinearLayout,通过动态添加ch ...

  8. android圆形波纹按钮,android自定义View——圆形波纹扫描效果

    蓝牙项目,考虑到后面可能会用到这个扫描的效果,所以参照大神写好的控件,增加了自己需要使用的接口.也顺便巩固一下自定义view中各种零碎的知识点. 需要的效果图 先放一个效果图,点击中心图片开始动画,再 ...

  9. Android自定义View实现QQ气泡效果

    首先我们来看一下最终的效果: 根据我们上边拆分出来的公式,我们分别看看每一个效果需要如何去实现: 红色圆:canvas.drawCircle 消息数字:canvas.drawText 拖拽粘性效果:c ...

  10. android 高仿ios开关,Android自定义view仿IOS开关效果

    本文主要讲解如何在 Android 下实现高仿 iOS 的开关按钮,并非是在 Android 自带的 ToggleButton 上修改,而是使用 API 提供的 onDraw.onMeasure.Ca ...

最新文章

  1. JZOJ 5643. 【NOI2018模拟4.10】最小代价
  2. Boost asio学习笔记之二—— 网络编程
  3. uniapp背景图片android不显示,uni-app网络图片在app不显示,小程序显示
  4. c语言md5函数 linux,Linux下C语言计算文件的md5值(长度32)
  5. 25、jdbc操作数据库(2)
  6. 通过实例理解 JDK8 的 CompletableFuture
  7. netpref 使用_使用PrefView监测.NET程序性能(一):Event Trace for Windows
  8. solidity之以太币支付
  9. [转]影响Cache的几个HTTP头信息
  10. SQL server 增、删、改代码
  11. 第四次作业3 四则运算试题生成
  12. PyTorch实现CNN
  13. Rocksdb参数总结
  14. windows vcpkg下载慢
  15. 连续均匀聚苯乙烯纳米微球造孔剂/氨基化聚苯乙烯微球/羧基功能化马来酸酉干(MA)聚苯乙烯微球
  16. 软件项目管理(第二版 宁涛)问答题(个人背诵)
  17. Eigen 对矩阵的每个元素取绝对值
  18. 面试官:你最擅长的软件测试领域在哪里啊?有什么发展计划吗?
  19. 研发部的人员素质要求及自我培养
  20. LDPC码简介(一)

热门文章

  1. 去除面部黑色素小妙招_减轻面部色素沉着的10种小妙招
  2. (附源码)计算机毕业设计SSM绝味鸭脖连锁店信息系统
  3. 洛谷P5149——会议座位【字典树 + 逆序对】
  4. 【分布式】熔断、降级傻傻分不清楚-熔断和降级的真实关系
  5. 社区医院与三级医院的检查检验贡献
  6. 解读手机拍照的各个参数(慢动作)
  7. 从面试7连挂到面面offer,我只用了一个月,面试20K+测试岗亲身经验分享.....
  8. 【骐程】【深信服测试开发面试】首次面试互联网
  9. MYSQL之ifnull(),nullif(),isnull()的用法
  10. 2022-03-行为经济学-光华管理学院-孟涓涓