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

Android带圆形数字进度的自定义进度条示例

程序员文章站 2023-12-21 15:24:04
开发 设计搞了一个带圆形进度的进度条,在github上逛了一圈,发现没有,自己撸吧。 先看界面效果: 主要思路是写一个继承progressbar的自定义vie...

开发

设计搞了一个带圆形进度的进度条,在github上逛了一圈,发现没有,自己撸吧。

先看界面效果:

Android带圆形数字进度的自定义进度条示例

主要思路是写一个继承progressbar的自定义view,不废话,直接上代码:

package com.fun.progressbarwithnumber;

import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.rectf;
import android.util.attributeset;
import android.util.typedvalue;
import android.widget.progressbar;

public class horizontalprogressbarwithnumber extends progressbar {

  private static final int default_text_size = 10;
  private static final int default_text_color = 0xfffc00d1;
  private static final int default_color_unreached_color = 0xffd3d6da;
  private static final int default_height_reached_progress_bar = 2;
  private static final int default_height_unreached_progress_bar = 2;
  private static final int default_circle_color = 0xff3f51b5;

  protected paint mpaint = new paint();
  // 字体颜色
  protected int mtextcolor = default_text_color;
  // 字体大小
  protected int mtextsize = sp2px(default_text_size);
  // 覆盖进度高度
  protected int mreachedprogressbarheight = dp2px(default_height_reached_progress_bar);
  // 覆盖进度颜色
  protected int mreachedbarcolor = default_text_color;
  // 未覆盖进度高度
  protected int munreachedprogressbarheight = dp2px(default_height_unreached_progress_bar);
  // 未覆盖进度颜色
  protected int munreachedbarcolor = default_color_unreached_color;
  // 圆的颜色
  protected int mcirclecolor = default_circle_color;

  protected int mrealwidth;

  protected boolean mifdrawtext = true;
  protected boolean mifdrawcircle = true;

  protected static final int visible = 0;

  public horizontalprogressbarwithnumber(context context, attributeset attrs) {
    this(context, attrs, 0);
  }

  public horizontalprogressbarwithnumber(context context, attributeset attrs, int defstyle) {
    super(context, attrs, defstyle);
    obtainstyledattributes(attrs);
    mpaint.settextsize(mtextsize);
    mpaint.setcolor(mtextcolor);
    mpaint.setantialias(true);
  }

  private void obtainstyledattributes(attributeset attrs) {
    // 获取自定义属性
    final typedarray attributes = getcontext().obtainstyledattributes(attrs, r.styleable.horizontalprogressbarwithnumber);
    mtextcolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_text_color, default_text_color);
    mtextsize = (int) attributes.getdimension(r.styleable.horizontalprogressbarwithnumber_progress_text_size, mtextsize);
    mcirclecolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_circle_color, default_circle_color);
    mreachedbarcolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_reached_color, mtextcolor);
    munreachedbarcolor = attributes.getcolor(r.styleable.horizontalprogressbarwithnumber_progress_unreached_color, default_color_unreached_color);
    mreachedprogressbarheight = (int) attributes.getdimension(r.styleable.horizontalprogressbarwithnumber_progress_reached_bar_height, mreachedprogressbarheight);
    munreachedprogressbarheight = (int) attributes.getdimension(r.styleable.horizontalprogressbarwithnumber_progress_unreached_bar_height, munreachedprogressbarheight);
    int textvisible = attributes.getint(r.styleable.horizontalprogressbarwithnumber_progress_text_visibility, visible);
    if (textvisible != visible) {
      mifdrawtext = false;
    }
    attributes.recycle();
    int left = (int) (mreachedprogressbarheight * 0.8), right = (int) (mreachedprogressbarheight * 0.8);
    int top = (int) (mreachedprogressbarheight * 0.3 + dp2px(1)), bottom = (int) (mreachedprogressbarheight * 0.3 + dp2px(1));
    setpadding(left, top, right, bottom);
  }

  @override
  protected synchronized void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    int width = measurespec.getsize(widthmeasurespec);
    int height = measureheight(heightmeasurespec);
    setmeasureddimension(width, height);
    mrealwidth = getmeasuredwidth() - getpaddingright() - getpaddingleft();
  }

  private int measureheight(int measurespec) {
    int result;
    int specmode = measurespec.getmode(measurespec);
    int specsize = measurespec.getsize(measurespec);
    if (specmode == measurespec.exactly) {
      result = specsize;
    } else {
      float textheight = (mpaint.descent() - mpaint.ascent());
      result = (int) (getpaddingtop() + getpaddingbottom() + math.max(
          math.max(mreachedprogressbarheight, munreachedprogressbarheight), math.abs(textheight)));
      if (specmode == measurespec.at_most) {
        result = math.min(result, specsize);
      }
    }
    return result;
  }


  @override
  protected synchronized void ondraw(canvas canvas) {
    canvas.save();
    canvas.translate(getpaddingleft(), getheight() / 2);

    boolean noneedbg = false;
    float radio = getprogress() * 1.0f / getmax();
    float progressposx = (int) (mrealwidth * radio);
    string text = getprogress() + "%";

    float textwidth = mpaint.measuretext(text);
    float textheight = (mpaint.descent() + mpaint.ascent()) / 2;

    float radius = (mreachedprogressbarheight + getpaddingbottom() + getpaddingtop()) / 2;

    // 覆盖的进度
    float endx = progressposx;
    if (endx > -1) {
      mpaint.setcolor(mreachedbarcolor);
      rectf rectf = new rectf(0, 0 - getpaddingtop() - getpaddingbottom(),
          endx, mreachedprogressbarheight - getpaddingbottom());
      canvas.drawroundrect(rectf, 25, 25, mpaint);
    }

    // 未覆盖的进度
    if (!noneedbg) {
      float start = progressposx;
      mpaint.setcolor(munreachedbarcolor);
      rectf rectf = new rectf(start, 0 - getpaddingtop() - getpaddingbottom(),
          mrealwidth + getpaddingright() - radius, mreachedprogressbarheight - getpaddingbottom());
      canvas.drawroundrect(rectf, 25, 25, mpaint);
    }

    // 圆
    if (mifdrawcircle) {
      mpaint.setcolor(mcirclecolor);
      canvas.drawcircle(progressposx, 0, radius, mpaint);
    }

    // 文本
    if (mifdrawtext) {
      mpaint.setcolor(mtextcolor);
      canvas.drawtext(text, progressposx - textwidth / 2, -textheight, mpaint);
    }

    canvas.restore();

  }

  /**
   * dp 2 px
   */
  protected int dp2px(int dpval) {
    return (int) typedvalue.applydimension(typedvalue.complex_unit_dip, dpval, getresources().getdisplaymetrics());
  }

  /**
   * sp 2 px
   */
  protected int sp2px(int spval) {
    return (int) typedvalue.applydimension(typedvalue.complex_unit_sp, spval, getresources().getdisplaymetrics());
  }

}

使用

在布局文件中加入:

<com.fun.progressbarwithnumber.horizontalprogressbarwithnumber
    android:id="@+id/hpbwn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    fun:progress_circle_color="#ff000000"
    fun:progress_reached_bar_height="20dp"
    fun:progress_reached_color="#ffff4081"
    fun:progress_text_color="#ffffffff"
    fun:progress_text_size="14sp"
    fun:progress_unreached_bar_height="20dp"
    fun:progress_unreached_color="#ffbcb4e8" />
  • progress_reached_bar_height:当前进度的高度
  • progress_unreached_bar_height:剩余进度的高度
  • progress_text_size:圆圈内文字的大小

注意:

当前进度和剩余进度的高度要一致,圆圈大小和圆圈内文字的大小要配合java代码调整。

项目源码:progressbarwithnumber_jb51.rar

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

上一篇:

下一篇: