软件编程
位置:首页>> 软件编程>> Android编程>> Android自定义圆形倒计时进度条

Android自定义圆形倒计时进度条

作者:yanzhenjie1003  发布时间:2021-09-11 06:17:08 

标签:Android,倒计时,进度条

本文实例为大家分享了Android倒计时进度条展示的具体代码,供大家参考,具体内容如下

效果预览

Android自定义圆形倒计时进度条

源代码传送门:https://github.com/yanzhenjie/CircleTextProgressbar

实现与原理

这个文字圆形的进度条我们在很多APP中看到过,比如APP欢迎页倒计时,下载文件倒计时等。

分析下原理,可能有的同学一看到这个自定义View就慌了,这个是不是要继承View啊,是不是要绘制啊之类的,答案是:是的。但是我们也不要担心,实现这个效果实在是so easy。下面就跟我一起来看看核心分析和代码吧。

原理分析

首先我们观察上图,需要几个部分组成:
1. 外面逐渐增加/减少的圆形进度条。
2. 圆形进度条中间的展示文字。
3. 圆形进度条外面包裹的圆。
4. 圆形进度条中间的填充色。
5. 字体颜色/填充颜色点击变色:ColorStateList类。

我们分析得出需要四个部分。一看有文字,那么第一个想到的自然是TextView啦,正好可以少做一个字体颜色的记录。中间的填充颜色(原型暂且不考虑)点击时变色,需要ColorStateList类来记录。剩下的进度条、轮廓圆和填充圆是需要我们绘制的。

我封装的CircleTextProgressbar特色

CircleTextProgressbar支持自动倒计时,自动减少进度,自动增加进度等。

如果需要自动走进度的话,设置完你自定义的属性后调用start()方法就可以自动倒计时了,如果想走完后再走一遍自动进度调用一下reStart()就OK了。

如果不想自动走进度,你可以通过setProgress()来像系统的progress一样修改进度值。


// 和系统普通进度条一样,0-100。
progressBar.setProgressType(CircleTextProgressbar.ProgressType.COUNT);
// 改变进度条。
progressBar.setProgressLineWidth(30);// 进度条宽度。
// 设置倒计时时间毫秒,默认3000毫秒。
progressBar.setTimeMillis(3500);
// 改变进度条颜色。
progressBar.setProgressColor(Color.RED);
// 改变外部边框颜色。
progressBar.setOutLineColor(Color.RED);
// 改变圆心颜色。
progressBar.setInCircleColor(Color.RED);
// 如果需要自动倒计时,就会自动走进度。
progressBar.start();
// 如果想自己设置进度,比如100。
progressBar.setProgress(100);

踩坑的过程

其实好久没有写过自定义View了,有些东西还真忘记了,所以写这个View的时候又把之前的坑踩了一遍,为了避免其它同学也被坑,这里把我踩的坑也记录下。

View绘制区域

这里我遇到一个问题,因为我们继承的TextView文字多了就是长的,那么绘制出来的圆长宽是一样的,所以在TextView上绘制出来的圆只能看到一部分或者是椭圆的。所以我们要把View的绘制区域扩大。当时我第一个想到的是layout()方法,因为当View的父布局onLayout()的时候会调用View的layout()来让子View布局,我重写了layout方法:


@Override
public void layout(int left, int top, int right, int bottom) {
int w = right - left;
int h = bottom - top;
int size = w > h ? w : h;

if (w > h) {
bottom += (size - h);
} else {
right += (size - w);
}
super.layout(left, top, right, bottom);
}

这段代码的原理就是宽和高,那个大,就把view扩大到这么最大的这个值。

当放了一个View在Layout时,效果出来没问题,但是我放多个View到LinearLayout中的时候发现几个View重叠了,哦舍特。我恍然大悟啊,这尼玛人家Layout已经把我绘制区域的宽高指定了,我强行去占领别的View的了。so,我应该重写onMeasure()啊,在测量宽高的时候就告诉父Layout我要多大的地盘:


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int size = width > height ? width : height;
setMeasuredDimension(size, size);
}

这段代码的意思更容易理解,就是看super.onMeasure测量的时候的宽高哪个大,就把宽高都设置成最大的这个值。告诉父Layout我要多大的地盘,那么等我绘制的时候我想怎么玩就怎么玩。

绘制View的实现

来源:http://blog.csdn.net/yanzhenjie1003/article/details/51889239

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com