自定义view系列(7)--SwitchView
来源:互联网 发布:matlab矩阵拆成列向量 编辑:程序博客网 时间:2024/06/06 07:45
自定义view系列(7)--SwitchView
需求描述
草图如下:
公司产品的新版本中要实现一个效果,需求如下:
- 定义4种状态:未知-休息-上班-下班
- 要锁定‘未知’状态,锁定之后,未知状态不可点击
- 用户可以点击除了锁定状态的之外的任意状态,滑块自动滑动到指定状态并触发回调去请求接口,如果请求失败,则控制滑块再滑动到之前的位置。
- 用户可以滑动滑块到任意位置,如果滑动到锁定状态,要再次滑动重置到之前的状态。如果滑动到其他位置,则触发回调去请求接口,如果请求失败,则控制滑块再滑动到之前的位置。
- 如果滑块滑动到两个状态之间,则松开手之后,滑块要自动滑动到距离最近的状态上,然后触发回调去请求接口,如果请求失败,则控制滑块再滑动到之前的位置。
实现思路
- 由于既有点击操作又有滑动操作,且要实现滑块与下方文本的解耦,所以选择继承ViewGroup实现,这里选择继承LinearLayout。
- 文本内容直接使用canvas绘制
- 对于锁定位置直接把事件拦截掉
- 使用属性动画进行相关的滑动
- 剩下的就是一些具体的逻辑处理
最终实现的效果
默认效果
自定义文本及字体颜色、大小
自定义插值器,锁定位置(锁定位置为2),滑动时不展示文本
所有可用API及作用
源码分析
主要说一下实现过程中一些需要注意的地方
1. 测量
在onMeasure()方法中,主要针对MeasureSpec.AT_MOST
这种测量模式做了处理:使用默认的宽高设置,对于其他测量模式,统一使用父view传递过来的尺寸。这里需要注意的是使用默认宽高尺寸时,需要与父view传递过来的尺寸作对比,取最小值作为最终的view宽高大小,不然会造成margin值设置失效的问题。
2.绘制
在绘制时,View与ViewGroup是有区别的:对于View,我们在onDraw(Canvas canvas)中绘制,但对于ViewGroup,我们应该在dispatchDraw(Canvas canvas)方法中进行绘制。因为在ViewGroup中,onDraw(Canvas canvas)方法不一定会执行,只有在为ViewGroup设置了背景等情况时,才会执行onDraw(Canvas canvas)方法。而dispatchDraw(Canvas canvas)方法不管是View还是ViewGroup,都会执行。那么既然dispatchDraw(Canvas canvas)方法必定会执行,为什么在View中不使用dispatchDraw(Canvas canvas)方法而使用onDraw(Canvas canvas)方法方法呢?其实主要是为了节省性能,因为只有符合相关条件才会执行onDraw(Canvas canvas)方法,而什么条件下才会执行绘制这些事情Android已经帮我们做好了。
从View的源码中我们可以看到onDraw(Canvas canvas)和dispatchDraw(Canvas canvas)执行的条件:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
dispatchDraw(Canvas canvas)是每个ViewGroup都会重写的方法,用来向子view分发绘制事件,所以我们在继承某个ViewGroup重写dispatchDraw(Canvas canvas)方法时,如果我们先调用super.dispatchDraw(canvas)
,则会先绘制子view,如果后调用super.dispatchDraw(canvas)
,则会先绘制我们自己的内容。这里的先后顺序要弄清楚。
3.根据任意点的坐标判断该点是否属于某个位置范围内
这里我使用RectF类存储每个item的边界值,RectF类提供了contains方法用来判断任意点坐标是否在范围内:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
最后再说两句
- 第一句:项目地址:SwitchViewProject
- 第二句:依赖方式参见github中的readme,如果对你有帮助的话,还请不吝赏赐一个star或fork,万分感谢!
- 自定义view系列(7)--SwitchView
- 自定义view系列(7)--SwitchView
- 自定义switchview
- android自定义开关SwitchView
- [Android开发] 自定义View之重写View非常简单实现开关按钮SwitchView
- Android_自定义切换控件SwitchView
- Android 自定义SwitchView(滑动开关)
- 自定义SwitchView控件升级版
- SwitchView安卓自定义控件--切换开关
- 自定义View系列目录索引
- 自定义view-日历系列
- 【自定义View系列】android自定义View概述
- 【自定义view系列】View的measure过程
- 【自定义view系列】View的layout过程
- 【自定义View系列】View的draw过程
- 自定义View系列:广告倒计时View
- 自定义View系列的总结
- 自定义View系列(6)--RatingBarView
- CSS发展史整理
- git命令rebase
- 一些干货——优秀Java程序员发福利啦!
- 面试题5. 从尾到头打印链表
- 实现类
- 自定义view系列(7)--SwitchView
- encodeURI与encodeURIComponent方法的区别 如果你使用的get方法提交表单肯定要考虑到输入项目的编码解码问题。 解决这个问题大家一般都使用encodeURI或者en
- JDBC_操纵MySQL最底层的方法封装详解
- 获取整个页面包括滚动条的宽度,获取滚动条宽度
- Bootstrap栅格系统
- UnicodeDecodeError解决办法
- 基于距离的计算方法
- caffe入门示例--mnist手写数子集训练
- WEB开发入门总结-记用户注册功能