内容简介:一直没有自己梳理一遍 View 体系的知识,以前写自定义 View 一涉及细节就全靠 Google。最近在 deepin 下搞了一份 AOSP 项目,准备从源码中再学习一遍自定义 View 的写法。在开始之前,先写了一个简单的自定义 View,用来复习自定义 View 的流程。TaggedSeekBar 在 SeekBar 的基础上加了一个显示进度值的标签,也可以当做 ProgressBar 使用,最终效果如下(压缩的比较惨,重在领会精神):TaggedSeekBar 直接继承自 View,虽然比较简陋,但
一直没有自己梳理一遍 View 体系的知识,以前写自定义 View 一涉及细节就全靠 Google。最近在 deepin 下搞了一份 AOSP 项目,准备从源码中再学习一遍自定义 View 的写法。在开始之前,先写了一个简单的自定义 View,用来复习自定义 View 的流程。
TaggedSeekBar 在 SeekBar 的基础上加了一个显示进度值的标签,也可以当做 ProgressBar 使用,最终效果如下(压缩的比较惨,重在领会精神):
知识点
TaggedSeekBar 直接继承自 View,虽然比较简陋,但确实包含了自定义 View 的大部分知识点。比如:
- View 的坐标体系
- Paint 基本属性
- Canvas 基本绘制函数
- onMeasure 测量自身
- onTouchEvent 处理用户交互
详情就不展开说了,有很多大佬都专门写过的。
流程
写自定义 View 时,最重要的第一步是「拆」。良好的拆解可以使 xml 中的参数更易理解,也可以简化 onDraw 中的绘制坐标计算过程。
我把 TaggedSeekBar 拆分成三部分:progress bar,thumb 和 tag(tag 分为箭头和本体),详情如图(看我充满灵魂的手绘):
拆分以满足需求为主,尽量保证良好的可扩展性。拆完之后就可以开始编码了
1. xml属性配置
当多个自定义 attr 的 name 冲突时,可以将 attr 的定义提取到外层,结构是这样的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="progressWidth" format="dimension|reference"/>
<declare-styleable name="TaggedSeekBar">
<attr name="progressWidth"/>
</declare-styleable>
<declare-styleable name="XXProgressBar">
<attr name="progressWidth"/>
</declare-styleable>
</resources>
复制代码
2. 读取属性,配置默认值
xml 配置参数的缺点是无法限制属性关联,每个属性都可能没写,所以获取属性的时候都需要填入默认值。
设置的默认值需要考虑到 View 元素相关性,尽量少用固定值,这样能尽可能降低上手难度。
3. 测量和定位
View 的 layout 方式符合我们的需求,不需要重写 onLayout。onMeasure 需要重写来支持 wrap_content 。进度条是水平方向的,所以 width 能多大就取多大,height 可以 wrap_content ,最小高度只要显示完整内容就好。
//当height的测量模式是 AT_MOST 时, //height = tagHeight+ThumbHeight+indicatorHeight height = paddingBottom + paddingTop + thumbRadius * 2 + thumbStrokeWidth * 2 + indicatorHeight + tagHeight).toInt() 复制代码
4. 分层绘制
onDraw 中后绘制的内容会覆盖在上面,这决定了坐标计算的顺序。TaggedSeekBar 中的绘制顺序是:进度条底色->进度条->thumb->tag
1.进度条底色(圆角矩形)
2.进度条(圆角矩形,覆盖在底色上)
3.Thumb(圆形)
4.tagIndicator(三角形)
绘制 api 不包含的图形可以用 Path,复用之前需要 reset。
5.tag(圆角矩形)
5. 响应 Touch 事件
事件的处理从响应 ACTION_DOWN 开始,拿到 event 的坐标之后首先要确定点击位置是否支持拖动。
如果不支持就当无事发生,支持的话就开始处理 ACTION_MOVE 并重绘自身。
关于 Listener 的配置还是以满足需求为主,这里只添加了两种:一是随拖动实时回调进度,二是松手后回调一次。
Tips
在编码和写博客期间遇到了一些小问题,顺便记录一下。
1. attrs.xml 里 name 冲突
之前没太注意,一般都是换个名字对付过去了。正确解法应该是这样的: 【代码】
2. 真机录制 gif
用模拟器运行代码的时候可以使用 LICEcap 直接录制 gif,在手机上运行就稍微复杂了点,adb 不支持录制 gif,可以采取录制视频再转为 gif 的方式。转换 工具 推荐 ffmpeg 命令,一行代码搞定:
- -i | 输入文件
- -vf scale=360:-1 |转换的同时缩放尺寸,宽高比为 360:-1,-1 表示保持比例自适应高度
刚接触 ffmpeg,感觉用处很多,研究之后单独写一下吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- [Vue 2.x Todo 教程练习参考答案] 标为完成练习参考答案
- [Vue 2.x Todo 教程练习参考答案] 添加todo练习参考答案
- [Vue 2.x Todo 教程练习参考答案] 入门仪式_Hello_Vue练习参考答案
- python二级练习(4)
- python二级练习(6)
- python二级练习(7)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Four
Scott Galloway / Portfolio / 2017-10-3 / USD 28.00
NEW YORK TIMES BESTSELLER USA TODAY BESTSELLER Amazon, Apple, Facebook, and Google are the four most influential companies on the planet. Just about everyone thinks they know how they got there.......一起来看看 《The Four》 这本书的介绍吧!