Android弹性圆点指示器绘制详解

流程简析

    整个控件的加载运行流程如下图所示:
在这里插入图片描述

onMeasure()处理

        onMeasure()的任务是对控件的尺寸进行初步的测量。本控件支持三种风格:1.实心圆点风格 2.空心圆点风格 3.长条风格。圆点风格和长条风格就在这个方法里出现了分支。在这里插入图片描述
        跳进onMeasureStrip()看看长条风格下是怎么进行初步测量的。代码对AT_MOST在控件长宽上都进行了处理,也就是说它是支持自适应的(wrap_content)。当然,图片显示的是主要的代码。
在这里插入图片描述
        再看看圆点风格下的初步绘制是怎样的。其实和长条风格的代码差不多,只是现在需要注意的是圆点半径。
在这里插入图片描述

onLayout()处理

        之所以说onMeasure()是初步测量,是因为onMeasure()的测量只考虑了自己的尺寸,如宽100dp,高30dp,没有考虑和其他控件之间的尺寸协调。而这个协调尺寸的操作就是在onLayout()中完成的。这个时候测量出来的尺寸就是控件真正的尺寸了。由于本控件并不是布局控件所以可以暂时不考虑onLayout()。
    当然,如果控件要支持Margin和Padding的话,也要放在这个方法里进行处理。

onDraw()处理

        完成了onMeasure()和onLayout(),实际上我们想要的图案并不会显示出来,因为前两个方法只完成了测量的操作,还没有真正把图案“画”出来。onDraw()就是负责绘制任务的。
        这里首先要明白一点,我们平时看的电影也好动画也好,它们都是由一帧一帧的图片组成的,快速地切换这些图片就有了“动”的效果。而每调用一次onDraw()就是绘制了一帧的图片。为了达到流畅的效果,onDraw()尽量只做和绘制有关的操作,不要做太多的计算工作,否则就容易出现一卡一卡的现象了。
        代码如下,根据不同的风格进行不同的绘制,但其实原理是一样的。下面只分析圆点风格的绘制
在这里插入图片描述
代码如下,先绘制背景,再绘制闪光效果,最后才绘制圆点
在这里插入图片描述
为什么是这样的顺序呢?因为在默认情况下先画出来的图案会被之后画出来的图案遮住,就像下面这样。当然,也可以学习一下有关android PorterDuffXfermode的知识,图层操作可以变得更灵活。
在这里插入图片描述

初识invalidate()和postInvalidate()

        仔细的话会发现onDraw()并不是public方法,那该如何让控件多次绘制呢?在主线程中调用invalidate(),或在子线程中调用postInvalidate()即可。
        为什么当初不把onDraw()设计为public方法直接调用呢?主要是担心线程安全问题。在主线程中(有时又叫UI线程)调用invalidate()立即完成当前的更新UI请求。在子线程中调用postInvalidate(),则会把这个UI更新请求放在一个消息队列中等待处理,所有的UI任务始终都是在主线程中完成的。
        一个控件如果支持动画,那么它就会多次调用invalidate()或postInvalidate()来维持“动”的效果,而onMeasure()、onLayout(),和onDraw()又是在UI线程中完成。这也就是为什么上文强调不要在onDraw()做过多和绘制无关的操作。前面的UI请求花太多时间来处理,后面的UI请求就只能傻傻地等待了。

添加动画效果

        为了使控件用起来不那么生硬,可以在控件中添加动画效果。实现动画效果需要一定的基础,如果您对Android属性动画(ValueAnimator)不了解的话,建议先学习属性动画的基本使用再继续阅读本文章。为了更好理解弹性效果的实现,贝塞尔曲线也是需要提前了解的。

弹性圆点动画的分解图如下:
在这里插入图片描述
利用Android 的 Path绘制
在这里插入图片描述
弹出时的闪光效果分解图如下:
在这里插入图片描述
        由于动画效果的代码较长所以就不贴出来了,可以在文章末尾的github地址中看完整代码。

基本使用

在build.gradle(project)中添加如下内容

repositories {
        google()
        jcenter()
 }

在build.gradle(app)添加如下内容

implementation 'com.github.PYJTLK:StickyIndicator:1.0'

在布局文件中设置相关属性
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020013115540383.png
如果不设置宽高,则必须设置如下两个个属性:
        1.radius圆点的半径
        2.interval圆点的间隔

java demo代码如下
在这里插入图片描述

效果

空心圆点(实心圆点风格的效果是一样的,只是·蓝色圆环变成实心的)
在这里插入图片描述
长条风格效果
在这里插入图片描述
当然,如果不需要闪光效果,只要设置app:hideFlash="false"即可。

这是项目github地址:https://github.com/PYJTLK/StickyIndicator

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值