欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-02-22 08:38:15
本文实例为大家分享了android自定义带动画效果的圆形progressbar,供大家参考,具体内容如下最近有个需求显示进度,尾部还要有一标示,像下边这样使用自定义view的方式实现,代码如下,很简单...

本文实例为大家分享了android自定义带动画效果的圆形progressbar,供大家参考,具体内容如下

最近有个需求显示进度,尾部还要有一标示,像下边这样

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()+"%");
  }
}

效果图

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

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

拓展

拓展也很简单,加一个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);

效果如下

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

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