最近项目有要用到环形的进度条,Github上有一个类似的DashedCircularProgress控件,但是他画的进度是通过设置画笔的虚线效果来实现间隔的:progresspaint.setPathEffect(new DashPathEffect(new float[]{dashWith,dashSpace},dashSpace));如果内层还有一层圆环,在动态设置时,内层和外层有细微的偏差.于是我在原有基础上改了一个,实现了我要的效果(设置进度时可以选择加动画或者不加动画):
控件实现:
这个控件继承relativeLayout,在onDraw时做了两件事:
1、先画出底部的黑色环形;
2、按照当时的进度值画出对应比例的外层绿色环形.
对外提供一个接口,回调当前进度值:
public interface OnValuechangelistener { voID onValueChange(float value);}
核心绘制类:
InternalCirclePainterImp2,绘制内层的黑色的环形:
/** * @author Chuck */public class InternalCirclePainterImp2 implements InternalCirclePainter { private RectF internalCircle;//画出圆弧时,圆弧的外切矩形 private Paint internalCirclePaint; private int color; private float startAngle = 270f; int arcQuantity=100;//等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔 float ratio=0.5f;//每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1 private int wIDth; private int height; private int internalstrokeWIDth = 48;//圆环宽度 public InternalCirclePainterImp2(int color,int progressstrokeWIDth,int arcQuantity,float ratio) { this.color = color; this.internalstrokeWIDth = progressstrokeWIDth; this.arcQuantity = arcQuantity; if(ratio>0&&ratio<1){ this.ratio = ratio; } init(); } private voID init() { initExternalCirclePainter(); } private voID initExternalCirclePainter() { internalCirclePaint = new Paint(); internalCirclePaint.setAntiAlias(true); internalCirclePaint.setstrokeWIDth(internalstrokeWIDth); internalCirclePaint.setcolor(color); internalCirclePaint.setStyle(Paint.Style.stroke); } //圆弧外切矩形 private voID initExternalCircle() { internalCircle = new RectF(); float padding = internalstrokeWIDth * 0.5f; internalCircle.set(padding,padding,wIDth - padding,height - padding); initExternalCirclePainter(); } @OverrIDe public voID draw(Canvas canvas) { float eachAngle=360f/arcQuantity; float eachArcAngle=eachAngle*ratio; for(int i=0;i<arcQuantity*2;i++){ if(i%2==0){//遇到偶数就画圆弧,基数则跳过 canvas.drawArc(internalCircle,startAngle+eachAngle*i/2,eachArcAngle,false,internalCirclePaint); } else{ continue; } } } public voID setcolor(int color) { this.color = color; internalCirclePaint.setcolor(color); } @OverrIDe public int getcolor() { return color; } @OverrIDe public voID onSizeChanged(int height,int wIDth) { this.wIDth = wIDth; this.height = height; initExternalCircle(); }}
ProgresspainterImp2,绘制内层的黑色的环形:
/** * @author Chuck */public class ProgresspainterImp2 implements Progresspainter { private RectF progressCircle; private Paint progresspaint; private int color = color.RED; private float startAngle = 270f; private int internalstrokeWIDth = 48; private float min; private float max; private int wIDth; private int height; private int currentPecent;//当前的百分比 int arcQuantity=100;//等分(圆弧加间隔),ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1 public ProgresspainterImp2(int color,float min,float max,float ratio) { this.color = color; this.min = min; this.max = max; this.internalstrokeWIDth = progressstrokeWIDth; this.arcQuantity = arcQuantity; this.ratio = ratio; init(); Log.e("ProgresspainterImp","构造函数执行"); } private voID init() { initInternalCirclePainter(); } private voID initInternalCirclePainter() { progresspaint = new Paint(); progresspaint.setAntiAlias(true); progresspaint.setstrokeWIDth(internalstrokeWIDth); progresspaint.setcolor(color); progresspaint.setStyle(Paint.Style.stroke); } //初始化外切的那个矩形 private voID initInternalCircle() { progressCircle = new RectF(); float padding = internalstrokeWIDth * 0.5f; progressCircle.set(padding,height - padding); initInternalCirclePainter(); } @OverrIDe public voID draw(Canvas canvas) { float eachAngle=360f/arcQuantity; float eachArcAngle=eachAngle*ratio; int quantity=2*arcQuantity*currentPecent/100; for(int i=0;i<quantity;i++){ if(i%2==0){//遇到偶数就画圆弧,基数则跳过 canvas.drawArc(progressCircle,progresspaint); } else{ continue; } } } public float getMin() { return min; } public voID setMin(float min) { this.min = min; } public float getMax() { return max; } public voID setMax(float max) { this.max = max; } public voID setValue(float value) { this.currentPecent = (int) (( 100f * value) / max); } @OverrIDe public voID onSizeChanged(int height,int wIDth) { Log.e("ProgresspainterImp","onSizeChanged执行"); this.wIDth = wIDth; this.height = height; initInternalCircle(); } public int getcolor() { return color; } public voID setcolor(int color) { this.color = color; progresspaint.setcolor(color); }}
可以自定义的属性:
<declare-styleable name="CircularLoadingVIEw"> <attr name="base_color" format="color" /> <!--内层圆环的颜色--> <attr name="progress_color" format="color" /><!--进度圆环的颜色--> <attr name="max" format="float" /><!--最小值--> <attr name="min" format="float" /><!--最大值--> <attr name="duration" format="integer" /><!--动画时长--> <attr name="progress_stroke_wIDth" format="integer" /><!--圆环宽度--> <!--等分(圆弧加间隔),和100个空白间隔--> <attr name="argQuantity" format="integer" /> <!--每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1--> <attr name="ratio" format="float" /></declare-styleable>
调用:
main_activity.xml:
<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:paddingBottom="@dimen/activity_vertical_margin" androID:paddingleft="@dimen/activity_horizontal_margin" androID:paddingRight="@dimen/activity_horizontal_margin" androID:paddingtop="@dimen/activity_vertical_margin" xmlns:custom="http://schemas.androID.com/apk/res-auto" androID:background="#ffffff" > <!--自定义控件,继承relativeLayout--> <qdong.com.mylibrary.CircularLoadingVIEw androID:ID="@+ID/simple" custom:base_color="@color/pager_bg" custom:min="0" custom:max="100" custom:argQuantity="100" custom:ratio="0.6" custom:progress_color="@androID:color/holo_green_light" custom:progress_icon="@mipmap/ic_launcher" custom:duration="1000" custom:progress_stroke_wIDth="28" androID:layout_centerInParent="true" androID:layout_wIDth="200dp" androID:layout_height="200dp"> <relativeLayout androID:layout_centerInParent="true" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <TextVIEw androID:layout_centerInParent="true" androID:textSize="20sp" androID:layout_centerHorizontal="true" androID:ID="@+ID/number" androID:text="0" androID:gravity="center" androID:textcolor="@color/pager_bg" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" /> </relativeLayout> </qdong.com.mylibrary.CircularLoadingVIEw> <button androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="Set_Value" androID:ID="@+ID/button" androID:layout_alignParentBottom="true" androID:layout_alignParentStart="true"/> <button androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="Animation" androID:ID="@+ID/button3" androID:layout_aligntop="@+ID/button" androID:layout_alignParentEnd="true"/></relativeLayout>
MainActivity:
findVIEwByID(R.ID.button).setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { try { mDashedCircularProgress.setValue(66);//没有动画的,直接设置 } catch (Exception e) { e.printstacktrace(); } }});findVIEwByID(R.ID.button3).setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { try { mDashedCircularProgress.setValue(0);//无动画,归零 mDashedCircularProgress.setValueWithAnimation(100,2000);//带动画 } catch (Exception e) { e.printstacktrace(); } }});
Github地址:https://github.com/506954774/AndroidCircularLoadingView
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android自定义环形LoadingView效果全部内容,希望文章能够帮你解决Android自定义环形LoadingView效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)