先上gif效果图:
上图中,蓝色的进度条为自定义进度条
注意!!!源码在文末
背景
要实现一个进度条,大部分情况下,都是需要进行自定义的。因为原生就算你自定义了背景图片,但是一旦进度条的高度,超过了一定的范围,且进度在1%左右的时候,就会看到明显的“卡边”情况。
就是进度条如果是圆角的背景,但是如果是小进度的时候,进度会显示出一个长方形。因此为了一了百了,则有了这篇文章,自定义进度条!
思路
要实现自定义进度条,首先,是需要有canvas的基础知识的。如果没有,则需要自行学习。
伸手党看到这里,可以关闭网页了。
首先,如开头的图片所示,进度条,有以下要素:
(1)区分为当前进度颜色,和背景进度颜色
(2)有圆角
(3)点击后,有扩散的水波纹效果,然后从百分之一百回到当前进度
大概要点就是这些。下面开始定义要素。
(1)有一个状态变量,是控制进度条的状态的,例如说默认状态,选中状态,非选中状态
(2)控制颜色的变量
(3)进度条的值
(4)点击时候的参数
再者,我们需要思考一下问题:
(1)默认情况,是没有进度的,所以只需要绘制一个默认的背景即可
(2)非选中状态,进度条是从0开始到目标值的,中间有个过渡的动画
(3)选中状态,先触发水波纹动画,当动画到达最长边的时候,则会有消失,然后播放进度条动画
实现
(1)水波纹
直接使用canvas中的drawCircle方法绘制即可,通过ValueAnimator进行半径的变化,然后即可实现
(2)普通从0-xx的进度条动画,也是通过ValueAnimator进行控制即可
(3)基于(2)的基础上,如果进度条从100-xx也是通过ValueAnimator变化即可。
整体绘制实现,都需要放到onDraw方法中,通过标识(Boolean)的控制,控制绘制的方法,绘制不同的效果,onDraw核心代码如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!hadInit()) {
return;
}
if (getStatus() == TYPE_STATUS_DEFAULT) {
drawBgInfo(canvas);
return;
}
if (!needDraw()) {
return;
}
if (!needAnim()) {
drawChangeBg(canvas);
//不需要动画,直接画进度条
drawProgressInfo(canvas);
return;
}
//绘制顺序:
//非选中模式,进度条慢慢叠加,直到进度值
//选中模式,水波纹填充后,进度条渐渐显示,数值从100退回到目标值
if (mDrawingRipple) {
//绘制水波纹
drawRippleInfo(canvas);
}
if (mDrawingCustomBg) {
//绘制修改后的背景
drawChangeBg(canvas);
}
if (mDrawingProgress) {
//绘制进度条
drawProgressInfo(canvas);
}
}
注意
(1)对于动画的实现,用到了ValueAnimator,注意释放的时机
(2)对于recyclerview中使用该进度条控件,请注意复用问题
(3)对于进度条的值换算,通过实际px值换算即可
(4)对于圆角,在绘制的过程中,你会发现低进度的情况(1%)圆角失效,
同时,网上大部分自定义进度条也是的,这里就不一一放出他们的博客地址了。实现方法有很多,我这里是直接使用clipPath后再绘制。
就这么多,链接在下面
that's all----------------------------------------------------
类名:
SelectionProgressHorizontalBarView
SelectionProgressVerticalBarView