查看原文
其他

自定义进度条就是如此简单—手把手教你撸一个精美的环形View

2017-08-04 BraveJoy 终端研发部

前言介绍

手把手教你撸一个自定义环形进度条

BraveJoy的博客地址:

http://www.jianshu.com/p/3cfcdde05ea8

正文 

前几天在朋友圈看到了一个圆形的循环的加载效果,于是尝试着实现了一下,照例先放个GitHub传送门:https://github.com/SuperKotlin/CircleProgressBar

先来看一下效果图(fuck!在真机上是很流畅的,切成gif有点掉帧!)。 

看到这样的一个效果,该如何去实现呢?

总体思路

  1. 自定义属性:圆弧的颜色和宽度,一开始加载进度的位置;

  2. 画出需要的效果:设置不同的角度,使用画笔paint在canvas上绘制圆弧; 好的,接下来我们就按照这个思路一步一步的撸:

1.自定义我们需要的属性:

在values文件夹下新建文件attrs.xml

<declare-styleable name="CircleProgressView">        <!--画笔宽度-->        <attr name="progress_paint_width" format="dimension" />        <!--画笔颜色-->        <attr name="progress_paint_color" format="color" />        <!--加载进度的开始位置-->        <attr name="progress_location" format="enum">            <enum name="left" value="1" />            <enum name="top" value="2" />            <enum name="right" value="3" />            <enum name="bottom" value="4" />        </attr>    </declare-styleable>

然后在自定义View中获取并设置这些属性: 首先,来声明我们的属性类型:

private Paint mPaintCurrent;//圆弧画笔    private float mPaintWidth;//画笔宽度    private int mPaintColor = Color.RED;//画笔颜色    private int location;//从哪个位置开始    private float startAngle;//开始角度

获取自定义属性值:

//获取属性值 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView); location = array.getInt(R.styleable.CircleProgressView_progress_location, 2); mPaintWidth = array.getDimension(R.styleable.CircleProgressView_progress_paint_width, dip2px(context, 4));//默认4dp mPaintColor = array.getColor(R.styleable.CircleProgressView_progress_paint_color, mPaintColor); array.recycle();

初始化和赋值:

//画笔->进度圆弧mPaintCurrent = new Paint(); mPaintCurrent.setAntiAlias(true); mPaintCurrent.setStrokeWidth(mPaintWidth); mPaintCurrent.setStyle(Paint.Style.STROKE); mPaintCurrent.setColor(mPaintColor); mPaintCurrent.setStrokeCap(Paint.Cap.ROUND);if (location == 1) {    startAngle = -180; } else if (location == 2) {//默认从上侧开始    startAngle = -90; } else if (location == 3) {    startAngle = 0; } else if (location == 4) {    startAngle = 90; }

2.画出需要的效果:设置不同的角度,使用画笔paint在canvas上绘制圆弧:

注意:绘制操作是在onDraw(Canvas canvas)方法中。

我们使用cancas的drawArc()方法来绘制圆弧,不清楚这个方法怎么使用以及里面的参数是什么意思的请看:自定义View_手把手教你撸出一个圆形加载进度条里面有详细介绍!首先来分析一下绘制这个圆弧的过程,我们分为两步,分别如图:

整个的效果可以拆分为这两个,第一个是从0°绘制到360°的位置,刚好是一个完整的圆形。第二个是从一个完整的圆形360°慢慢的减少到0°。至于如何让他循环不停地完成这两个过程,我们写个定时器不停地调用invalidate()就OK了。

第一个过程:我们只需要使drawArc方法中的sweepAngle(扫过的角度)从0增大到360就OK了,可以理解为按照顺时针方向一点一点的画出圆弧;

第二个过程:可以理解为按照顺时针方向一点一点的擦除圆弧,那么它的sweepAngle(扫过的角度)从360减小到0就OK了?错!!!,因为我们是顺时针擦除,所以应该加个负号,即从-360减小到-0就OK了。 OK,分析结束开始撸代码:我们定义一个变量sweepAngle=0,只需要在定时器里判断:

sweepAngle++;  
if (sweepAngle== 360) {         sweepAngle= -360;    } invalidate();

然后绘制:

canvas.drawArc(rectF, startAngle, sweepAngle, false, mPaintCurrent);

到此算是完成了整个效果,但是你会发现绘制的很慢,因为定时器就算每隔1毫秒绘制一次那么1毫秒也就仅仅绘制了1°而已,所以我们来设置一个比例参数mCurrent=0。

sweepAngle++;    
if (sweepAngle== 100) {         sweepAngle= -100;    } invalidate();

然后绘制:

float sweepAngle = 360 * mCurrent / 100; canvas.drawArc(rectF, startAngle, sweepAngle, false, mPaintCurrent);

下面我把全部代码贴上来:

attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="CircleProgressBar">        <!--画笔宽度-->        <attr name="progress_paint_width" format="dimension" />        <!--画笔颜色-->        <attr name="progress_paint_color" format="color" />        <!--加载进度的开始位置-->        <attr name="progress_location" format="enum">            <enum name="left" value="1" />            <enum name="top" value="2" />            <enum name="right" value="3" />            <enum name="bottom" value="4" />        </attr>    </declare-styleable></resources>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical">    <com.example.zhuyong.circleprogressbar.CircleProgressBar        android:id="@+id/circle_view"        android:layout_width="150dp"        android:layout_height="150dp"        app:progress_location="top"        app:progress_paint_color="#FF4081"        app:progress_paint_width="4dp" /></LinearLayout>


demo地址:

https://github.com/SuperKotlin/CircleProgressBar


博客地址:


http://www.jianshu.com/p/3cfcdde05ea8

终端研发部提倡 没有做不到的,只有想不到的。

在这里获得的不仅仅是技术! 



让心,在阳光下学会舞蹈

让灵魂,在痛苦中学会微笑

—终端研发部—



如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809   

微信公众号:终端研发部


            

这里学到的不仅仅




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存