[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,感觉用处很多,研究之后单独写一下吧。


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

查看所有标签

猜你喜欢:

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

指数型组织

指数型组织

萨利姆•伊斯梅尔 (Salim Ismail)、迈克尔•马隆 (Michael S. Malone)、尤里•范吉斯特 (Yuri van Geest) / 苏健 / 浙江人民出版社 / 2015-8-1 / CNY 69.90

《指数型组织》是一本指数级时代企业行动手册。作者奇点大学创始执行理事萨利姆·伊斯梅尔归纳了指数型组织的11个强大属性,并提出了建立指数型组织的12个关键步骤。通过自己创建的一套“指数商”测试题,伊斯梅尔还测量出了指数型组织世界100强。  为什么小米、海尔和阿里巴巴能进入“指数型组织世界100强”名单?“独角兽”Uber、Airbnb、谷歌等知名企业是如何指数化自己的组织的?  未......一起来看看 《指数型组织》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具