[Android UI] 自定义 View 练习——TaggedSeekBar

栏目: IOS · Android · 发布时间: 5年前

内容简介:一直没有自己梳理一遍 View 体系的知识,以前写自定义 View 一涉及细节就全靠 Google。最近在 deepin 下搞了一份 AOSP 项目,准备从源码中再学习一遍自定义 View 的写法。在开始之前,先写了一个简单的自定义 View,用来复习自定义 View 的流程。TaggedSeekBar 在 SeekBar 的基础上加了一个显示进度值的标签,也可以当做 ProgressBar 使用,最终效果如下(压缩的比较惨,重在领会精神):TaggedSeekBar 直接继承自 View,虽然比较简陋,但

一直没有自己梳理一遍 View 体系的知识,以前写自定义 View 一涉及细节就全靠 Google。最近在 deepin 下搞了一份 AOSP 项目,准备从源码中再学习一遍自定义 View 的写法。在开始之前,先写了一个简单的自定义 View,用来复习自定义 View 的流程。

TaggedSeekBar 在 SeekBar 的基础上加了一个显示进度值的标签,也可以当做 ProgressBar 使用,最终效果如下(压缩的比较惨,重在领会精神):

[Android UI] 自定义 View 练习——TaggedSeekBar

知识点

TaggedSeekBar 直接继承自 View,虽然比较简陋,但确实包含了自定义 View 的大部分知识点。比如:

  1. View 的坐标体系
  2. Paint 基本属性
  3. Canvas 基本绘制函数
  4. onMeasure 测量自身
  5. onTouchEvent 处理用户交互

详情就不展开说了,有很多大佬都专门写过的。

流程

写自定义 View 时,最重要的第一步是「拆」。良好的拆解可以使 xml 中的参数更易理解,也可以简化 onDraw 中的绘制坐标计算过程。

我把 TaggedSeekBar 拆分成三部分:progress bar,thumb 和 tag(tag 分为箭头和本体),详情如图(看我充满灵魂的手绘):

[Android UI] 自定义 View 练习——TaggedSeekBar

拆分以满足需求为主,尽量保证良好的可扩展性。拆完之后就可以开始编码了

1. xml属性配置

[Android UI] 自定义 View 练习——TaggedSeekBar

当多个自定义 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 元素相关性,尽量少用固定值,这样能尽可能降低上手难度。

[Android UI] 自定义 View 练习——TaggedSeekBar

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.进度条底色(圆角矩形)

[Android UI] 自定义 View 练习——TaggedSeekBar

2.进度条(圆角矩形,覆盖在底色上)

[Android UI] 自定义 View 练习——TaggedSeekBar

3.Thumb(圆形)

[Android UI] 自定义 View 练习——TaggedSeekBar

4.tagIndicator(三角形)

[Android UI] 自定义 View 练习——TaggedSeekBar

绘制 api 不包含的图形可以用 Path,复用之前需要 reset。

5.tag(圆角矩形)

[Android UI] 自定义 View 练习——TaggedSeekBar

5. 响应 Touch 事件

事件的处理从响应 ACTION_DOWN 开始,拿到 event 的坐标之后首先要确定点击位置是否支持拖动。

[Android UI] 自定义 View 练习——TaggedSeekBar

如果不支持就当无事发生,支持的话就开始处理 ACTION_MOVE 并重绘自身。

[Android UI] 自定义 View 练习——TaggedSeekBar

关于 Listener 的配置还是以满足需求为主,这里只添加了两种:一是随拖动实时回调进度,二是松手后回调一次。

Tips

在编码和写博客期间遇到了一些小问题,顺便记录一下。

1. attrs.xml 里 name 冲突

之前没太注意,一般都是换个名字对付过去了。正确解法应该是这样的: 【代码】

2. 真机录制 gif

用模拟器运行代码的时候可以使用 LICEcap 直接录制 gif,在手机上运行就稍微复杂了点,adb 不支持录制 gif,可以采取录制视频再转为 gif 的方式。转换 工具 推荐 ffmpeg 命令,一行代码搞定:

[Android UI] 自定义 View 练习——TaggedSeekBar
  • -i | 输入文件
  • -vf scale=360:-1 |转换的同时缩放尺寸,宽高比为 360:-1,-1 表示保持比例自适应高度

刚接触 ffmpeg,感觉用处很多,研究之后单独写一下吧。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法的乐趣

算法的乐趣

王晓华 / 人民邮电出版社 / 2015-4 / 79.00元

算法之大,大到可以囊括宇宙万物的运行规律;算法之小,小到寥寥数行代码即可展现一个神奇的功能。算法的应用和乐趣在生活中无处不在: 历法和二十四节气计算使用的是霍纳法则和求解一元高次方程的牛顿迭代法; 音频播放器跳动的实时频谱背后是离散傅立叶变换算法; DOS时代著名的PCX图像文件格式使用的是简单有效的RLE压缩算法; RSA加密算法的光环之下是朴实的欧几里德算法、蒙哥马利算......一起来看看 《算法的乐趣》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具