Android UI-薄荷健康尺子
Posted 小陈乱敲代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android UI-薄荷健康尺子相关的知识,希望对你有一定的参考价值。
效果
源码:HenCoder-CustomView: HenCoder-三篇自定义View仿写 (gitee.com)
原的
仿的
功能点分析
- 根据尺子的量程 和 分度值 绘制尺子的静态效果
- 内容滑动,计算滑动边界
- 惯性滑动,智能定位
- 计算当前刻度值
- 基准线居中
实现分析
绘制尺子刻度
- 分度值:即最小刻度值,就是在测量仪器所能读出的最小值,指测量工具上相邻的两个刻度之间的最小格的数值
- 绘制尺子刻度,肯定要用到循环,最简单的办法,知道尺子的刻度总数,即可把尺子绘制出来。
- 尺子的刻度数根据 量程和分度值确定。上图尺子同样的量程 有两个分度值,尺子的刻度数完全不同
- 刻度数的计算:量程/分度值。 比如:
- 度量范围20~100,量程是80,分度值是1。 一共80个刻度
- 但凡事总有例外,度量范围0~100,量程100,分度值1,并不是100个刻度,而是一百零一个刻度。
- 0也算一个刻度,0 ~ 100 是101个数。1~100才是100个数。 程序员应该很好理解吧,毕竟从入行开始,数的起始就不是1了🐶
- 尺子的刻度一般都是10进制,则取余数
i % 10 == 0
表明是大刻度,其余的都是小刻度。 - 定义变量,刻度的长款,间隔。已经知道总刻度数,通过循环遍历即可绘制出尺子的静态样式
- 绘制文字比较简单 每次取余数
i % 10 == 0
表示大刻度,需要绘制文字,坐标微调即可。
尺子的滑动
- 滑动分两种,内容滑动和拖拽滑动。
- 内容滑动场景是:ScrollView ,ListView,RecyclerView,在有限的位置固定的空间内可以展示无限内容。
- 拖拽滑动指View内容不变,位置变化。应用场景是微信语音,视频电话的小窗口。
- 尺子的滑动是内容滑动
- 重写
onTouchEvent()
。记录每次手指滑动产生的坐标,上一次坐标与当前坐标相减,计算滑动距离。 - 在move事件中,调用
scrollBy()
传入滑动距离,内容滑动完成
- 重写
- 惯性滑动组件介绍
- 仅仅使用
scrollBy()
滑动无惯性,效果比较生硬,与系统滑动组件的体验相差比较多 - 结合
VelocityTracker
和Scroller
使滑动产生惯性 VelocityTracker
收集手指滑动路径的坐标用作路程,传入时间,计算出速度。Scroller
滑动辅助类,并不实现View滚动。它的作用好像属性动画,计算一段时间内数字变化, 比如:一秒内从0增长到100。 开发者监听数字变化从而实现动画
- 仅仅使用
- 惯性滑动实现
- 重写
onTouchEvent()
调用VelocityTracker.addMovement(event)
收集手势滑动信息 - 在up事件,
VelocityTracker.computeCurrentVelocity(1000)
计算一秒内滑动距离产生的速度 - 速度计算结果 ,手指左滑 速度正数 ,手指右滑 速度负数。
- 速度正数使坐标增加 ,负数使坐标减少。这里会引发一个问题
- 调用
Scroller.fling()
- fling 参数解析
- startX:开始位置
- minX-maxX:区间 ,根据速度计算x值 的范围在 minX maxX之间
- velocityX 速度的影响
- 比如:手指右滑
- 期望效果 x轴正方向移动 值增加
- 实际效果 速度负数 Scroller.fling动画结果 x轴负方向移动 值减少
- 期望效果与实际效果正好相反 所以速度取相反数 效果正好
- fling总结
- startX开始位置 如 :100
- 受速度影响 计算结果 会从100开始增加或减少。
- 但不是无限增加或减少,计算结果的边界在 minX最小值,maxX最大值 之间
- 调用
invalidate()
触发view重绘, - 重写
computeScroll()
,获取Scroller
动画结果 ,调用scrollTo()
实现内容滚动
- 重写
滑动边界
滑动边界与view的大小是两个概念
view的内容绘制在canvas上,canvas是一块无限大的画布,View有坐标系,左上角是原点(0,0),惨van无限大,坐标系也是无限大的。
View的宽高则是在无限大的canvas从原点开始圈出一块位置展示内容。
如下图,用户的可视范围只是100*100,但无限大的canvas仍然存在。假设在(200,200)的位置画了一个点,虽然用户看不见,但是它仍然存在。
上一节使用scrollBy()
和scrollTo()
实现内容的滑动
其内部原理是修改View的两个属性mScrollX,mScrollY
。mScrollX,mScrollY
表示内容在X轴Y轴的滚动距离,也可以说是确定View的展示的原点。
举例说明:
- 自定义View,宽高都是100
- 两点坐标确定一个矩形,默认原点(0,0) 由于宽高100,另一点坐标(100,100)。View展示canvas (0,0),(100,100)两点坐标圈出的部分
- 沿X轴移动距离100后,原点坐标(100,0),另一点坐标(200,100)。View展示canvas (100,0),(200,100)两点坐标圈出的部分
所以想要实现View内容滑动的边界,就要限制X轴坐标的取值范围,也就是mScrollX
属性的范围,从0到X。
那么如何计算滑动范围呢?
滑动范围 = 大刻度数_大刻度宽 + 小刻度数_小刻度宽 + 间隔数*间隔宽
基准线居中
其实这个东西吧 属于会了不难,难了不会,经验问题,不知道的可能想半天也没想出来。
先说结论:基准线x轴坐标 = view宽度/2 + mScrollX
就能达到滚动时居中效果。
分析
- 假设View的宽高都为100
- 画一条长度为10的X轴居中的线段,坐标点(50,10)
- 这条线段只是看起来居中,在view的可视范围(0,0),(100,100)内居中,
- 它并不是画在View上,而是画在canvas,view只是圈出一个范围
- 当内容水平滑动,x值不断改变,线段的坐标也要随着滑动不断变化,才能维持居中的效果
- 代表水平滑动距离的变量是
mScrollX
线段坐标点为 (mScrollX +50,10)
智能定位
业务描述
当滑动到两个刻度之间,四舍五入自动定位到最近的那个刻度,比如:滑动到11.6,分度值是1,左右两个刻度分别是11,12。四舍五入滑动到12。
应用场景
- 惯性滑动后需要智能定位
- up手势之后,如果速度过小,无法出发惯性滑动,则需要智能定位
实现过程
这块挺复杂的,没办法详细说 很容易乱,我的思路不一定是最好的,当作参考
- 核心思路是利用等比例换算。
- 预先知道总滑动距离,知道当前滑动值,能够计算出滑动比例。
- 滑动比例 == 数值比例,通过比例计算出当前的测量值
- 根据分度值单位四舍五入,求出定位值,计算出定位值的X轴坐标
mScrollX
-定位值的X轴坐标 = 滑动距离。求出滑动距离后利用Scroller.startScroll()
进行滑动
只绘制可视区域内容
之前几点完成之后就算是可以正常使用的组件了,原本是不打算做可视区域绘制的(懒)
但是在调试的时候发现绘制内容过多会很卡,不流畅z
比如:度量范围1~100,分度值是1,需要绘制100个刻度。分度值0.1,需要绘制1k个刻度,分度值0.01,需要绘制1w个刻度,卡顿非常明显了,简直不能用。
计算可视区域非常简单。view的可见区域 = x轴坐标范围 = 滚动距离 + view的宽度
x坐标在范围内视为可见,不在范围内视为不可见
private fun isVisibleArea(x: Int): Boolean
//view的可见区域 = x轴坐标范围 = 滚动距离 + view的宽度
val offset = 20 //偏移量
val start =scrollX-offset
val end =scrollX+measuredWidth+ offset
return x in start..end
override fun onDraw(canvas: Canvas)
super.onDraw(canvas)
//简化代码
if (isVisibleArea(x))
drawLine(i, canvas)
drawText(i, canvas)
文末
要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、架构师筑基必备技能
1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……
二、Android百大框架源码解析
1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程
三、Android性能优化实战解析
- 腾讯Bugly:对字符串匹配算法的一点理解
- 爱奇艺:安卓APP崩溃捕获方案——xCrash
- 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
- 百度APP技术:Android H5首屏优化实践
- 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
- 携程:从智行 Android 项目看组件化架构实践
- 网易新闻构建优化:如何让你的构建速度“势如闪电”?
- …
四、高级kotlin强化实战
1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》
-
从一个膜拜大神的 Demo 开始
-
Kotlin 写 Gradle 脚本是一种什么体验?
-
Kotlin 编程的三重境界
-
Kotlin 高阶函数
-
Kotlin 泛型
-
Kotlin 扩展
-
Kotlin 委托
-
协程“不为人知”的调试技巧
-
图解协程:suspend
五、Android高级UI开源框架进阶解密
1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
六、NDK模块开发
1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习
七、Flutter技术进阶
1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)
…
八、微信小程序开发
1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓
以上是关于Android UI-薄荷健康尺子的主要内容,如果未能解决你的问题,请参考以下文章