android实现圆形渐变进度条-kb88凯时官网登录

时间:2020-05-16
阅读:
免费资源网 - https://freexyz.cn/

最近项目中使用到了渐变效果的圆形进度条,网上找了很多渐变效果不够圆滑,两个渐变颜色之间有明显的过渡,或者有些代码画出来的效果过渡不美观,于是自己参照写了一个,喜欢的朋友可以参考或者直接使用。

先上一张效果图,视频录制不太好,不过不影响效果

<a href=https://freexyz.cn/dev/android/ target=_blank class=infotextkey>android</a>实现圆形渐变进度条

下面开始介绍实现代码,比较简单,直接贴代码吧

1、声明自定义属性

在项目的valuse文件夹下新建attrs.xml,在里面定义自定义控件需要的属性


    
    
    
    
    
    
    

2、自定义一个进度条roundprogres继承view类

package com.blankj.progressring;
import android.animation.valueanimator;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.matrix;
import android.graphics.paint;
import android.graphics.rect;
import android.graphics.rectf;
import android.graphics.sweepgradient;
import android.graphics.typeface;
import android.util.attributeset;
import android.util.log;
import android.view.view;
import android.view.animation.linearinterpolator;
import org.jetbrains.annotations.nullable;
/**
 * 类描述:渐变的圆形进度条
 *
 * @author:lusy
 * @date :2018/10/17
 */
public class roundprogress extends view {
  private static final string tag = "roundprogress";
  /**
   * 背景圆环画笔
   */
  private paint bgpaint;
  /**
   * 白色标记画笔
   */
  private paint iconpaint;
  /**
   * 进度画笔
   */
  private paint progresspaint;
  /**
   * 进度文本画笔
   */
  private paint textpaint;
  /**
   * 背景圆环的颜色
   */
  private int bgcolor;
  /**
   * 线条进度的颜色
   */
  private int iconcolor;
  private int[] progresscolor;
  /**
   * 中间进度百分比的字符串的颜色
   */
  private int textcolor;
  /**
   * 中间进度百分比的字符串的字体大小
   */
  private float textsize;
  /**
   * 圆环的宽度
   */
  private float roundwidth;
  /**
   * 最大进度
   */
  private int max;
  /**
   * 当前进度
   */
  private float progress;
  /**
   * 是否显示中间的进度
   */
  private boolean textisdisplayable;
  /**
   * 圆环半径
   */
  private int mradius;
  private int center;
  private float startangle = -90;
  private float currentangle;
  private float currentprogress;
  public roundprogress(context context) {
    this(context, null);
  }
  public roundprogress(context context, @nullable attributeset attrs) {
    super(context, attrs);
    typedarray mtypedarray = context.obtainstyledattributes(attrs, r.styleable.roundprogress);
    //获取自定义属性和默认值
    bgcolor = mtypedarray.getcolor(r.styleable.roundprogress_bgcolor, color.parsecolor("#2d2d2d"));
    iconcolor = mtypedarray.getcolor(r.styleable.roundprogress_linecolor, color.parsecolor("#ffffff"));
    textcolor = mtypedarray.getcolor(r.styleable.roundprogress_textcolor, color.parsecolor("#ffffff"));
    textsize = mtypedarray.getdimension(r.styleable.roundprogress_textsize, 15);
    roundwidth = mtypedarray.getdimension(r.styleable.roundprogress_roundwidth, 5);
    max = mtypedarray.getinteger(r.styleable.roundprogress_maxprogress, 100);
    textisdisplayable = mtypedarray.getboolean(r.styleable.roundprogress_textisdisplayable, true);
    progresscolor = new int[]{color.parsecolor("#747eff"), color.parsecolor("#0018ff"), color.transparent};
    mtypedarray.recycle();
    initpaint();
  }
  public roundprogress(context context, @nullable attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
  }
  @override
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    //测量控件应占的宽高大小,此处非必需,只是为了确保布局中设置的宽高不一致时仍显示完整的圆
    int measurewidth = measurespec.getsize(widthmeasurespec);
    int measureheight = measurespec.getsize(heightmeasurespec);
    setmeasureddimension(math.min(measurewidth, measureheight), math.min(measurewidth, measureheight));
  }
  private void initpaint() {
    bgpaint = new paint();
    bgpaint.setstyle(paint.style.stroke);
    bgpaint.setantialias(true);
    bgpaint.setcolor(bgcolor);
    bgpaint.setstrokewidth(roundwidth);
    iconpaint = new paint();
    iconpaint.setstyle(paint.style.stroke);
    iconpaint.setantialias(true);
    iconpaint.setcolor(iconcolor);
    iconpaint.setstrokewidth(roundwidth);
    progresspaint = new paint();
    progresspaint.setstyle(paint.style.stroke);
    progresspaint.setantialias(true);
    progresspaint.setstrokewidth(roundwidth);
    textpaint = new paint();
    textpaint.setstyle(paint.style.stroke);
    textpaint.settypeface(typeface.default_bold);
    textpaint.setantialias(true);
    textpaint.setcolor(textcolor);
    textpaint.settextsize(textsize);
    textpaint.setstrokewidth(0);
  }
  @override
  protected void ondraw(canvas canvas) {
    /**
     * 画最外层的大圆环
     */
    //获取圆心的x坐标
    center = math.min(getwidth(), getheight()) / 2;
    // 圆环的半径
    mradius = (int) (center - roundwidth / 2);
    rectf oval = new rectf(center - mradius, center - mradius, center   mradius, center   mradius);
    //画背景圆环
    canvas.drawarc(oval, startangle, 360, false, bgpaint);
    //画进度圆环
    drawprogress(canvas, oval);
    canvas.drawarc(oval, startangle, currentangle, false, progresspaint);
    //画白色圆环
    float start = startangle   currentangle - 1;
    canvas.drawarc(oval, start, 3, false, iconpaint);
    //百分比文字
    int percent = (int) (((float) progress / (float) max) * 100);
    //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
    string text = string.valueof(percent) "%";
    rect textrect = new rect();
    textpaint.gettextbounds(text, 0, text.length(), textrect);
    if (textisdisplayable && percent >= 0) {
      //画出进度百分比文字
      float x = (getwidth() - textrect.width()) / 2;
      float y = (getheight()   textrect.height()) / 2;
      canvas.drawtext(text, x, y, textpaint);
    }
    if (currentprogress < progress) {
      currentprogress  ;
      postinvalidate();
    }
  }
  /**
   * 画进度圆环
   *
   * @param canvas
   * @param oval
   */
  private void drawprogress(canvas canvas, rectf oval) {
    float section = progress / 100;
    currentangle = section * 360;
    //把需要绘制的角度分成100等分
    float unitangle = (float) (currentangle / 100.0);
    for (float i = 0, end = currentprogress * unitangle; i <= end; i  ) {
      sweepgradient shader = new sweepgradient(center, center, progresscolor, new float[]{0.0f, section, 1.0f});
      matrix matrix = new matrix();
      matrix.setrotate(startangle, center, center);
      shader.setlocalmatrix(matrix);
      progresspaint.setshader(shader);
      canvas.drawarc(oval,
          startangle   i,
          1,
          false,
          progresspaint);
    }
  }
  @override
  protected void onsizechanged(int w, int h, int oldw, int oldh) {
    super.onsizechanged(w, h, oldw, oldh);
    //计算外圆半径 宽,高最小值-填充边距/2
    center = (math.min(w, h)) / 2;
    mradius = (int) ((math.min(w, h)) - roundwidth / 2);
  }
  public int getmax() {
    return max;
  }
  /**
   * 设置进度的最大值
   *
   * @param max
   */
  public void setmax(int max) {
    if (max < 0) {
      log.e(tag, "max progress not allow <0");
      return;
    }
    this.max = max;
  }
  /**
   * 获取进度
   *
   * @return
   */
  public float getprogress() {
    return progress;
  }
  /**
   * 设置进度
   *
   * @param progressvalue
   * @param useanima   是否需要动画
   */
  public void setprogress(float progressvalue, boolean useanima) {
    float percent = progressvalue * max / 100;
    if (percent < 0) {
      percent = 0;
    }
    if (percent > 100) {
      percent = 100;
    }
    //使用动画
    if (useanima) {
      valueanimator valueanimator = valueanimator.offloat(0, percent);
      valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() {
        @override
        public void onanimationupdate(valueanimator animation) {
          progress = (float) animation.getanimatedvalue();
          postinvalidate();
        }
      });
      valueanimator.setinterpolator(new linearinterpolator());
      valueanimator.setduration(1500);
      valueanimator.start();
    } else {
      this.progress = percent;
      postinvalidate();
    }
  }
  public int gettextcolor() {
    return textcolor;
  }
  public void settextcolor(int textcolor) {
    this.textcolor = textcolor;
  }
  public float gettextsize() {
    return textsize;
  }
  public void settextsize(float textsize) {
    this.textsize = textsize;
  }
  public float getroundwidth() {
    return roundwidth;
  }
  public void setroundwidth(float roundwidth) {
    this.roundwidth = roundwidth;
  }
  public int[] getprogresscolor() {
    return progresscolor;
  }
  public void setprogresscolor(int[] progresscolor) {
    this.progresscolor = progresscolor;
    postinvalidate();
  }
  public int getbgcolor() {
    return bgcolor;
  }
  public void setbgcolor(int bgcolor) {
    this.bgcolor = bgcolor;
  }
  public int geticoncolor() {
    return iconcolor;
  }
  public void seticoncolor(int iconcolor) {
    this.iconcolor = iconcolor;
  }
  public boolean istextisdisplayable() {
    return textisdisplayable;
  }
  public void settextisdisplayable(boolean textisdisplayable) {
    this.textisdisplayable = textisdisplayable;
  }
  public int getmradius() {
    return mradius;
  }
  public void setmradius(int mradius) {
    this.mradius = mradius;
  }
  public int getcenter() {
    return center;
  }
  public void setcenter(int center) {
    this.center = center;
  }
  public float getstartangle() {
    return startangle;
  }
  public void setstartangle(float startangle) {
    this.startangle = startangle;
  }
}

3、使用自定义进度条view

activity布局文件使用如下,为了方便测试效果,新增进度加、进度减,修改进度条颜色的按钮



  
    
免费资源网 - https://freexyz.cn/
返回顶部
顶部
网站地图