2020-08-03
关键字:
这篇文章记录一下我通过自定义View的方式实现的一个播放器进度条的过程以及完整源码。希望能起到一个“备忘”的作用,如果能再帮助到其他有同样需求的同学就更好了。
先来看看这个进度条的成品效果图:
想要自定义一个View,首先要知道我们需要实现什么样的效果。
要想实现我们想要的效果,就必须得能清晰地拆解效果图。
这个View总体上可以分为两个大类:
1、UI;
2、功能。
在 UI 上我们针对上面的效果图可以作如下拆解:
1、时间戳;
2、滑块;
3、进度条。
在功能上可以作如下拆解:
1、时长设置;
2、UI更新;
3、拖拉滑块改变播放进度;
4、事件回调。
将拆解逐个实现并最终拼凑成一个整体,就是笔者常用的自定义View流程模板。
1、UI实现
根据效果图来看,这个 View 通过继承 RelativeLayout 来自定义容器会更方便一点。当然这里必须强调笔者这样做仅仅是认为会更方便、开发周期上会更短一点而已。要说自定义 View 效果最好的还得是通过继承 View 来完全自己实现。但在实际工作过程中项目往往不会给你这么多的时间和精力来将一件“小事”做到极致。算是遗憾也算是无奈吧~
于是,一个 Java 类就出现了:
public class PlayerProgressBar extends RelativeLayout { }
自定义View的基调确定了,其它的子模块就好办了。
1.1、时间戳
时间戳元素通常使用两个。一个标示当前播放位置,另一个表示本次播放总时长或剩余时长。
笔者这边采用的是 当前位置 + 剩余时长 模式的时间戳。
具体的实现也简单,两个 TextView 分另放置在View的两侧,进度条下方。设置好各自的属性即可,没什么特别的。
1.2、滑块
滑块笔者这边直接是用一张图片来实现的。
为了显示地更有层次感,滑块上最好做点阴影效果,笔者为了方便直接找美工做切图实现了。
因此滑块也没什么特别的,就一个简单的 ImageView。
不过因为滑块是要运动,而在窗器中改变一个子View的位置最简单的办法就是改变这个子View的 LayoutParams 中的 margin 值。然后再通过容器父类的 requestLayout() 来更新整个View。
因此,在创建滑块ImageView时要记下它的 RelativeLayout.LayoutParams 对象。
滑块的切图贴出如下:
1.3、进度条
进度条笔者这边是直接使用Android自带的 ProgressBar 来实现的。
同样为了显示效果更逼真更好,进度槽还是建议加上阴影效果。如果你有美工可以支持你,直接让她做一个相关切图就最好了。
但是笔者没有!因此只能通过 xml 自定义 drawable 的方式勉强做了个槽+阴影的效果出来。
根据上面的效果图来看,确实不咋的,但它在手机上实际显示出来以后往往会比较小,一些缺陷也不会这么明显。凑合着能用。
这边笔者直接将这个xml代码贴出来了:
<?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <corners android:radius="3.5dp" /> <stroke android:color="#dddddd" android:width="1dp" /> </shape> </item> <item android:left="1dp" android:right="1dp" android:top="1dp" android:bottom="1dp"> <shape> <corners android:radius="2.5dp" /> <solid android:color="#ececec"/> </shape> </item> <item android:top="1dp" android:left="1dp" android:right="1dp" android:height="0.7dp"> <shape> <corners android:radius="0.3dp" /> <gradient android:endColor="#dddddd" android:startColor="#cdcdcd" android:type="linear" /> </shape> </item> <!-- 设置进度条颜色 --> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="3.5dp"/> <solid android:color="#EC1693"/> </shape> </clip> </item> </layer-list>