最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

Android自定义环形LoadingView效果

来源:动视网 责编:小OO 时间:2020-11-27 15:04:54
文档

Android自定义环形LoadingView效果

最近项目有要用到环形的进度条,Github上有一个类似的DashedCircularProgress控件,但是他画的进度是通过设置画笔的虚线效果来实现间隔的:progressPaint.setPathEffect(new DashPathEffect(new float[]{dashWith.dashSpace}.dashSpace));如果内层还有一层圆环,在动态设置时,内层和外层有细微的偏差.于是在原有基础上改了一个,实现了我要的效果(设置进度时可以选择加动画或者不加动画)。控件实现。这个控件继承RelativeLayout,在onDraw时做了两件事。1、先画出底部的黑色环形。2、按照当时的进度值画出对应比例的外层绿色环形。对外提供一个接口,回调当前进度值。
推荐度:
导读最近项目有要用到环形的进度条,Github上有一个类似的DashedCircularProgress控件,但是他画的进度是通过设置画笔的虚线效果来实现间隔的:progressPaint.setPathEffect(new DashPathEffect(new float[]{dashWith.dashSpace}.dashSpace));如果内层还有一层圆环,在动态设置时,内层和外层有细微的偏差.于是在原有基础上改了一个,实现了我要的效果(设置进度时可以选择加动画或者不加动画)。控件实现。这个控件继承RelativeLayout,在onDraw时做了两件事。1、先画出底部的黑色环形。2、按照当时的进度值画出对应比例的外层绿色环形。对外提供一个接口,回调当前进度值。
 这篇文章主要为大家详细介绍了Android自定义环形LoadingView效果的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近项目有要用到环形的进度条,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;//等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔
 float ratio=0.5f;//每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1

 public ProgressPainterImp2(int color, float min, float max, int progressStrokeWidth, int arcQuantity,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, padding , width - 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, startAngle+eachAngle*i/2, eachArcAngle, false, 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" /><!--圆环宽度-->

 <!--等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和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效果

最近项目有要用到环形的进度条,Github上有一个类似的DashedCircularProgress控件,但是他画的进度是通过设置画笔的虚线效果来实现间隔的:progressPaint.setPathEffect(new DashPathEffect(new float[]{dashWith.dashSpace}.dashSpace));如果内层还有一层圆环,在动态设置时,内层和外层有细微的偏差.于是在原有基础上改了一个,实现了我要的效果(设置进度时可以选择加动画或者不加动画)。控件实现。这个控件继承RelativeLayout,在onDraw时做了两件事。1、先画出底部的黑色环形。2、按照当时的进度值画出对应比例的外层绿色环形。对外提供一个接口,回调当前进度值。
推荐度:
标签: android 自定义 and
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top