本文实例为大家分享了android自定义带动画效果的圆形progressbar,供大家参考,具体内容如下
最近有个需求显示进度,尾部还要有一标示,像下边这样
使用自定义view的方式实现,代码如下,很简单注释的很清楚
文章最后我们拓展一下功能,实现一个带动画效果的进度条
package com.example.fwc.allexample.progressbar; import android.animation.valueanimator; import android.annotation.targetapi; import android.content.context; import android.content.res.typedarray; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.rectf; import android.graphics.typeface; import android.os.handler; import android.os.message; import android.text.textutils; import android.util.attributeset; import android.util.log; import android.view.view; import android.view.animation.decelerateinterpolator; import com.example.fwc.allexample.r; /** * created by fwc on 2016/7/6. */ public class circleprogressbar extends view { private context mcontext; private paint mpaint; private int mprogress = 0; private static int max_progress = 100; /** * 弧度 */ private int mangle; /** * 中间的文字 */ private string mtext; /** * 外圆颜色 */ private int outroundcolor; /** * 内圆的颜色 */ private int inroundcolor; /** * 线的宽度 */ private int roundwidth; private int style; /** * 字体颜色 */ private int textcolor; /** * 字体大小 */ private float textsize; /** * 字体是否加粗 */ private boolean isbold; /** * 进度条颜色 */ private int progressbarcolor; public circleprogressbar(context context) { this(context, null); } public circleprogressbar(context context, attributeset attrs) { this(context, attrs, 0); } public circleprogressbar(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); mcontext = context; init(attrs); } @targetapi(21) public circleprogressbar(context context, attributeset attrs, int defstyleattr, int defstyleres) { super(context, attrs, defstyleattr, defstyleres); mcontext = context; init(attrs); } /** * 解析自定义属性 * * @param attrs */ public void init(attributeset attrs) { mpaint = new paint(); typedarray typedarray = mcontext.obtainstyledattributes(attrs, r.styleable.circleprogressbar); outroundcolor = typedarray.getcolor(r.styleable.circleprogressbar_outcirclecolor, getresources().getcolor(r.color.colorprimary)); inroundcolor = typedarray.getcolor(r.styleable.circleprogressbar_incirclecolor, getresources().getcolor(r.color.colorprimarydark)); progressbarcolor = typedarray.getcolor(r.styleable.circleprogressbar_progresscolor, getresources().getcolor(r.color.coloraccent)); isbold = typedarray.getboolean(r.styleable.circleprogressbar_textbold, false); textcolor = typedarray.getcolor(r.styleable.circleprogressbar_textcolor, color.black); roundwidth = typedarray.getdimensionpixeloffset(r.styleable.circleprogressbar_linewidth, 20); typedarray.recycle(); } @override protected void ondraw(canvas canvas) { /** * 画外圆 */ super.ondraw(canvas); int center = getwidth() / 2; //圆心 int radius = (center - roundwidth / 2); //半径 mpaint.setcolor(outroundcolor); //外圆颜色 mpaint.setstrokewidth(roundwidth); //线的宽度 mpaint.setstyle(paint.style.stroke); //空心圆 mpaint.setantialias(true); //消除锯齿 canvas.drawcircle(center, center, radius, mpaint); //内圆 mpaint.setcolor(inroundcolor); radius = radius - roundwidth; canvas.drawcircle(center, center, radius, mpaint); //画进度是一个弧线 mpaint.setcolor(progressbarcolor); rectf rectf = new rectf(center - radius, center - radius, center radius, center radius);//圆弧范围的外接矩形 canvas.drawarc(rectf, -90, mangle, false, mpaint); canvas.save(); //平移画布之前保存之前画的 //画进度终点的小球,旋转画布的方式实现 mpaint.setstyle(paint.style.fill); //将画布坐标原点移动至圆心 canvas.translate(center, center); //旋转和进度相同的角度,因为进度是从-90度开始的所以-90度 canvas.rotate(mangle - 90); //同理从圆心出发直接将原点平移至要画小球的位置 canvas.translate(radius, 0); canvas.drawcircle(0, 0, roundwidth, mpaint); //画完之后恢复画布坐标 canvas.restore(); //画文字将坐标平移至圆心 canvas.translate(center, center); mpaint.setstrokewidth(0); mpaint.setcolor(textcolor); if (isbold) { //字体加粗 mpaint.settypeface(typeface.default_bold); } if (textutils.isempty(mtext)) { mtext = mprogress "%"; } //动态设置文字长为圆半径,计算字体大小 float textlength = mtext.length(); textsize = radius / textlength; mpaint.settextsize(textsize); //将文字画到中间 float textwidth = mpaint.measuretext(mtext); canvas.drawtext(mtext, -textwidth / 2, textsize / 2, mpaint); } public int getmprogress() { return mprogress; } /** * 设置进度 * * @return */ public void setmprogress(int p) { if (p > max_progress) { mprogress = max_progress; mangle = 360; } else { mprogress = p; mangle = 360 * p / max_progress; } } public string getmtext() { return mtext; } /** * 设置文本 * * @param mtext */ public void setmtext(string mtext) { this.mtext = mtext; } /** * 设置带动画的进度 * @param p */ public void setanimprogress(int p) { if (p > max_progress) { mprogress = max_progress; } else { mprogress = p; } //设置属性动画 valueanimator valueanimator = new valueanimator().ofint(0, p); //动画从快到慢 valueanimator.setinterpolator(new decelerateinterpolator()); valueanimator.setduration(3000); //监听值的变化 valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator animation) { int currentv = (integer) animation.getanimatedvalue(); log.e("fwc", "current" currentv); mangle = 360 * currentv / max_progress; mtext = currentv "%"; invalidate(); } }); valueanimator.start(); } }
自定义属性
布局文件中使用
activity中设置进度,显示文字
package com.example.fwc.allexample.progressbar; import android.support.v7.app.appcompatactivity; import android.os.bundle; import com.example.fwc.allexample.r; public class progressactivtiy extends appcompatactivity { circleprogressbar circleprogressbar; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_progress_activtiy); circleprogressbar = (circleprogressbar)findviewbyid(r.id.progress_bar); circleprogressbar.setprogress(65); circleprogressbar.setmtext(circleprogressbar.getprogress() "%"); } }
效果图
拓展
拓展也很简单,加一个setanimprogress(int p)设置动画效果:
/** * 设置带动画的进度 * @param p */ public void setanimprogress(int p) { if (p > max_progress) { mprogress = max_progress; } else { mprogress = p; } //设置属性动画 valueanimator valueanimator = new valueanimator().ofint(0, p); //动画从快到慢 valueanimator.setinterpolator(new decelerateinterpolator()); valueanimator.setduration(3000); //监听值的变化 valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator animation) { int currentv = (integer) animation.getanimatedvalue(); log.e("fwc", "current" currentv); mangle = 360 * currentv / max_progress; mtext = currentv "%"; invalidate(); } }); valueanimator.start(); }
在activity中调用这个方法
circleprogressbar.setanimprogress(65);
效果如下