Android自定义带动画效果的圆形ProgressBar
程序员文章站
2023-02-22 08:38:15
本文实例为大家分享了android自定义带动画效果的圆形progressbar,供大家参考,具体内容如下最近有个需求显示进度,尾部还要有一标示,像下边这样使用自定义view的方式实现,代码如下,很简单...
本文实例为大家分享了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(); } }
自定义属性
<declare-styleable name="circleprogressbar"> <attr name="outcirclecolor" format="color"></attr> <attr name="incirclecolor" format="color"></attr> <attr name="progresscolor" format="color"></attr> <attr name="textcolor" format="color"></attr> <attr name="textbold" format="boolean"></attr> <attr name="linewidth" format="dimension"></attr> </declare-styleable>
布局文件中使用
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:my="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.fwc.allexample.progressbar.progressactivtiy"> <com.example.fwc.allexample.progressbar.circleprogressbar android:id="@+id/progress_bar" android:layout_centerinparent="true" android:layout_width="150dp" android:layout_height="150dp" my:incirclecolor="#dcdcdc" my:outcirclecolor="#f0f0f0" my:progresscolor="#50ce7b" my:textbold="true" my:textcolor="#50ce7b" my:linewidth="5dp" /> </relativelayout>
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);
效果如下
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: EV剪辑导入的视频怎么添加字幕?
下一篇: 详解Angular如何正确的操作DOM