android开发分享Android自定义View实现时钟功能

最近在练习自定义view, 想起之前面试的时候笔试有道题是写出自定义一个时钟的关键代码. 今天就来实现一下. 步骤依然是先分析, 再上代码.实现效果view分析时钟主要分为五个部分:1、中心点: 圆心

最近在练习自定义view, 想起之前面试的时候笔试有道题是写出自定义一个时钟的关键代码. 今天就来实现一下. 步骤依然是先分析, 再上代码.

上述就是android开发分享Android自定义View实现时钟功能的全部内容,如果对大家有所用处且需要了解更多关于Android学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)

实现效果

Android自定义View实现时钟功能

view分析

时钟主要分为五个部分:

1、中心点: 圆心位置

2、圆盘: 以中心点为圆心,drawcircle画个圆

3、刻度:

paint有个aip, setpatheffect可以根据path画特效, 那么刻度就可以根据圆的path画一个矩形path的特效, 并且这个api只会画特效, 不会画出圆.

/**  * shape: 特效的path, 这里传一个矩形  * advance: 两个特效path之间的间距, 即两个矩形的left间距  * phase: 特效起始位置的偏移  * style: 原始path拐弯的时候特效path的转换方式,这里用rotate跟着旋转即可  */  pathdashpatheffect(path shape, float advance, float phase,                                style style)

刻度又分两种, 粗一点刻度: 3、6、9、12, 和细一点的刻度. 两种特效又可以用sumpatheffect合起来画

sumpatheffect(patheffect first, patheffect second) 

4、时分秒指针

时分秒指针都是一个圆角矩形, 先把他们的位置计算出来, 然后旋转圆心去绘制不同角度的指针.

5、动画效果

timertask每隔一秒计算时间, 根据时间去换算当前时分秒指针的角度, 动态变量只有三个角度.

实现源码

//  // created by skylar on 2022/4/19.  //  class clockview : view {      private var mtimer: timer? = null      private val mcirclepaint: paint = paint()      private val mpointerpaint: paint = paint()      private val mtextpaint: paint = paint()        private val mcirclepath: path = path()      private val mhourpath: path = path()      private val mminutepath: path = path()      private val msecondpath: path = path()        private lateinit var mpathmeasure: pathmeasure      private lateinit var msumpatheffect: sumpatheffect        private var mviewwidth = 0      private var mviewheight = 0      private var mcirclewidth = 6f      private var mradius = 0f      private var mrectradius = 20f      private var mhoursdegree = 0f      private var mminutesdegree = 0f      private var msecondsdegree = 0f      private var mcurrenttimeinsecond = 0l        constructor(context: context) : super(context)        constructor(context: context, attrs: attributeset?) : this(context, attrs, 0)        constructor(          context: context, attrs: attributeset?,          defstyleattr: int      ) : super(context, attrs, defstyleattr)        init {          mcirclepaint.color = color.black          mcirclepaint.isantialias = true          mcirclepaint.style = paint.style.stroke          mcirclepaint.strokewidth = mcirclewidth            mpointerpaint.color = color.black          mpointerpaint.isantialias = true          mpointerpaint.style = paint.style.fill            mtextpaint.color = color.black          mtextpaint.isantialias = true          mtextpaint.style = paint.style.fill          mtextpaint.textsize = 40f      }        override fun onsizechanged(w: int, h: int, oldw: int, oldh: int) {          super.onsizechanged(w, h, oldw, oldh)          mviewwidth = measuredwidth - paddingleft - paddingright          mviewheight = measuredheight - paddingtop - paddingbottom            mradius = mviewwidth / 2 - mcirclewidth          mcirclepath.addcircle(0f, 0f, mradius, path.direction.cw)            mpathmeasure = pathmeasure(mcirclepath, false)          val minutesshapepath = path()          val quartershapepath = path()          minutesshapepath.addrect(0f, 0f, mradius * 0.01f, mradius * 0.06f, path.direction.cw)          quartershapepath.addrect(0f, 0f, mradius * 0.02f, mradius * 0.06f, path.direction.cw)          val minutesdashpatheffect = pathdashpatheffect(              minutesshapepath,              mpathmeasure.length / 60,              0f,              pathdashpatheffect.style.rotate          )          val quarterdashpatheffect = pathdashpatheffect(              quartershapepath,              mpathmeasure.length / 12,              0f,              pathdashpatheffect.style.rotate          )          msumpatheffect = sumpatheffect(minutesdashpatheffect, quarterdashpatheffect)            val hourpointerheight = mradius * 0.5f          val hourpointerwidth = mradius * 0.07f          val hourrect = rectf(              -hourpointerwidth / 2,              -hourpointerheight * 0.7f,              hourpointerwidth / 2,              hourpointerheight * 0.3f          )          mhourpath.addroundrect(hourrect, mrectradius, mrectradius, path.direction.cw)            val minutepointerheight = mradius * 0.7f          val minutepointerwidth = mradius * 0.05f          val minuterect = rectf(              -minutepointerwidth / 2,              -minutepointerheight * 0.8f,              minutepointerwidth / 2,              minutepointerheight * 0.2f          )          mminutepath.addroundrect(minuterect, mrectradius, mrectradius, path.direction.cw)            val secondpointerheight = mradius * 0.9f          val secondpointerwidth = mradius * 0.03f          val secondrect = rectf(              -secondpointerwidth / 2,              -secondpointerheight * 0.8f,              secondpointerwidth / 2,              secondpointerheight * 0.2f          )          msecondpath.addroundrect(secondrect, mrectradius, mrectradius, path.direction.cw)            startanimator()      }        override fun ondraw(canvas: canvas?) {          super.ondraw(canvas)          if (canvas == null) {              return          }          canvas.translate((mviewwidth / 2).tofloat(), (mviewheight / 2).tofloat())            //画圆盘          mcirclepaint.patheffect = null          canvas.drawpath(mcirclepath, mcirclepaint)            //画刻度          mcirclepaint.patheffect = msumpatheffect          canvas.drawpath(mcirclepath, mcirclepaint)            //时分秒指针          mpointerpaint.color = color.black            canvas.save()          canvas.rotate(mhoursdegree)          canvas.drawpath(mhourpath, mpointerpaint)          canvas.restore()            canvas.save()          canvas.rotate(mminutesdegree)          canvas.drawpath(mminutepath, mpointerpaint)          canvas.restore()            canvas.save()          canvas.rotate(msecondsdegree)          canvas.drawpath(msecondpath, mpointerpaint)          canvas.restore()            //画中心点          mpointerpaint.color = color.white          canvas.drawcircle(0f, 0f, mradius * 0.02f, mpointerpaint)      }          private fun startanimator() {          val cal = calendar.getinstance()          val hour = cal.get(calendar.hour)  //小时          val minute = cal.get(calendar.minute)  //分          val second = cal.get(calendar.second)  //秒          mcurrenttimeinsecond = (hour * 60 * 60 + minute * 60 + second).tolong()            if (mtimer == null) {              mtimer = timer()          } else {              mtimer?.cancel()              mtimertask.cancel()          }          mtimer?.schedule(mtimertask, 0, 1000)      }        private var mtimertask: timertask = object : timertask() {          override fun run() {              mcurrenttimeinsecond++              computedegree()              invalidate()          }      }        //12小时 00:00:00 ~ 12:00:00      private fun computedegree() {          val secondsinoneroll = 12 * 60 * 60          val currentseconds = mcurrenttimeinsecond % secondsinoneroll            var leftseconds = currentseconds          val hours = currentseconds / 60 / 60          leftseconds = currentseconds - hours * 60 * 60          val minutes = leftseconds / 60          leftseconds -= minutes * 60          val seconds = leftseconds % 60            mhoursdegree = hours * 30f          mminutesdegree = minutes * 6f          msecondsdegree = seconds * 6f        }  }

以上就是android开发分享Android自定义View实现时钟功能的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ctvol.com/addevelopment/1239401.html

(0)
上一篇 2022年9月18日
下一篇 2022年9月18日

精彩推荐