当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义带动画效果的圆形ProgressBar

Android自定义带动画效果的圆形ProgressBar

2020年06月23日  | 移动技术网移动技术  | 我要评论

本文实例为大家分享了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);

效果如下

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网