全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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  # Android实现环形进度条  # Android自定义View实现环形进度条的思路与实例  # Android实现计步进度的环形Progress  # Android实现环形进度条的实例  # Android实现环形进度条代码  # Android应用中炫酷的横向和环形进度条的实例分享  # Android中制作进度框和环形进度条的简单实例分享  # Android环形进度条(安卓默认形式)实例代码  # android自定义环形对比图效果  # 将有  # 画出  # 自定义  # 跳过  # 我要  # 我在  # 基础上  # 上有  # 要用  # 可以选择  # 提供一个  # 不加  # 来实现  # 件事  # 改了  # 回调  # 时长  # 大家多多  # 最小值  # 实现了 


相关文章: 如何通过PHP快速构建高效问答网站功能?  如何用虚拟主机快速搭建网站?详细步骤解析  c++ stringstream用法详解_c++字符串与数字转换利器  如何高效完成独享虚拟主机建站?  如何在阿里云部署织梦网站?  如何选择CMS系统实现快速建站与SEO优化?  如何用搬瓦工VPS快速搭建个人网站?  Python lxml的etree和ElementTree有什么区别  建站主机是否等同于虚拟主机?  如何在Windows服务器上快速搭建网站?  开封网站制作公司,网络用语开封是什么意思?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  香港服务器租用费用高吗?如何避免常见误区?  北京建设网站制作公司,北京古代建筑博物馆预约官网?  网站制作多少钱一个,建一个论坛网站大约需要多少钱?  香港服务器选型指南:免备案配置与高效建站方案解析  C#怎么使用委托和事件 C# delegate与event编程方法  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  免费网站制作appp,免费制作app哪个平台好?  长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?  建站上市公司网站建设方案与SEO优化服务定制指南  如何在IIS中配置站点IP、端口及主机头?  Java解压缩zip - 解压缩多个文件或文件夹实例  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  javascript中的try catch异常捕获机制用法分析  无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?  网站图片在线制作软件,怎么在图片上做链接?  如何在云指建站中生成FTP站点?  css网站制作参考文献有哪些,易聊怎么注册?  如何通过西部建站助手安装IIS服务器?  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?  建站之星CMS五站合一模板配置与SEO优化指南  购物网站制作公司有哪些,哪个购物网站比较好?  较简单的网站制作软件有哪些,手机版网页制作用什么软件?  建站VPS能否同时实现高效与安全翻墙?  如何在宝塔面板创建新站点?  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  制作企业网站建设方案,怎样建设一个公司网站?  如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法  c# 在高并发下使用反射发射(Reflection.Emit)的性能  c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】  建站之星导航配置指南:自助建站与SEO优化全解析  如何快速建站并高效导出源代码?  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  C#如何使用XPathNavigator高效查询XML  如何快速搭建高效可靠的建站解决方案?  如何在新浪SAE免费搭建个人博客? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。