android开发分享Android自定义View实现水平带数字百分比进度条

这个进度条可以反映真实进度,并且完成百分比的文字时随着进度增加而移动的,所在位置也恰好是真实完成的百分比位置,效果如下: 思路如下:第一部分是左侧的蓝色直线,代表

这个进度条可以反映真实进度,并且完成百分比的文字时随着进度增加而移动的,所在位置也恰好是真实完成的百分比位置,效果如下:

Android自定义View实现水平带数字百分比进度条

思路如下:第一部分是左侧的蓝色直线,代表已经完成的进度;第二部分是右侧灰色的直线,代表未完成的进度;第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度。

最关键的部分就是要确定百分比文本的确切位置,这里用了paint的gettextbounds方法,得到文本的宽高,然后再精确确定它的位置。

view代码如下:

  public class numberprogressview extends view {       /**     * 进度条画笔的宽度(dp)     */    private int paintprogresswidth = 3;       /**     * 文字百分比的字体大小(sp)     */    private int painttextsize = 20;       /**     * 左侧已完成进度条的颜色     */    private int paintleftcolor = 0xff67aae4;       /**     * 右侧未完成进度条的颜色     */    private int paintrightcolor = 0xffaaaaaa;       /**     * 百分比文字的颜色     */    private int painttextcolor = 0xffff0077;       /**     * contxt     */    private context context;       /**     * 主线程传过来进程 0 - 100     */    private int progress;       /**     * 得到自定义视图的宽度     */    private int viewwidth;       /**     * 得到自定义视图的y轴中心点     */    private int viewcentery;       /**     * 画左边已完成进度条的画笔     */    private paint paintleft = new paint();       /**     * 画右边未完成进度条的画笔     */    private paint paintright = new paint();       /**     * 画中间的百分比文字的画笔     */    private paint painttext = new paint();       /**     * 要画的文字的宽度     */    private int textwidth;       /**     * 画文字时底部的坐标     */    private float textbottomy;       /**     * 包裹文字的矩形     */    private rect rect = new rect();       /**     * 文字总共移动的长度(即从0%到100%文字左侧移动的长度)     */    private int totalmovedlength;       public numberprogressview(context context, attributeset attrs) {      super(context, attrs);      this.context = context;      // 构造器中初始化数据      initdata();    }       /**     * 初始化数据     */    private void initdata() {         //设置进度条画笔的宽度      int paintprogresswidthpx = utils.dip2px(context, paintprogresswidth);         //设置百分比文字的尺寸      int painttextsizepx = utils.sp2px(context, painttextsize);         // 已完成进度条画笔的属性      paintleft.setcolor(paintleftcolor);      paintleft.setstrokewidth(paintprogresswidthpx);      paintleft.setantialias(true);      paintleft.setstyle(style.fill);         // 未完成进度条画笔的属性      paintright.setcolor(paintrightcolor);      paintright.setstrokewidth(paintprogresswidthpx);      paintright.setantialias(true);      paintright.setstyle(style.fill);         // 百分比文字画笔的属性      painttext.setcolor(painttextcolor);      painttext.settextsize(painttextsizepx);      painttext.setantialias(true);      painttext.settypeface(typeface.default_bold);       }       @override    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {      super.onmeasure(widthmeasurespec, heightmeasurespec);      getwidthandheight();    }       /**     * 得到视图等的高度宽度尺寸数据     */    private void getwidthandheight() {         //得到包围文字的矩形的宽高      painttext.gettextbounds("000%", 0, "000%".length(), rect);      textwidth = rect.width();      textbottomy = viewcentery + rect.height() / 2;         //得到自定义视图的高度      int viewheight = getmeasuredheight();      viewwidth = getmeasuredwidth();      viewcentery = viewheight / 2;      totalmovedlength = viewwidth - textwidth;       }       @override    protected void ondraw(canvas canvas) {      super.ondraw(canvas);         //得到float型进度      float progressfloat = progress / 100.0f;         //当前文字移动的长度      float currentmovedlentgh = totalmovedlength * progressfloat;         //画左侧已经完成的进度条,长度为从veiw左端到文字的左侧      canvas.drawline(0, viewcentery, currentmovedlentgh, viewcentery, paintleft);         //画右侧未完成的进度条,这个进度条的长度不是严格按照百分比来缩放的,因为文字的长度会变化,所以它的长度缩放比例也会变化      if (progress < 10) {        canvas.drawline(currentmovedlentgh + textwidth * 0.5f, viewcentery, viewwidth, viewcentery, paintright);      } else if (progress < 100) {        canvas.drawline(currentmovedlentgh + textwidth * 0.75f, viewcentery, viewwidth, viewcentery, paintright);      } else {        canvas.drawline(currentmovedlentgh + textwidth, viewcentery, viewwidth, viewcentery, paintright);      }         //画文字(注意:文字要最后画,因为文字和进度条可能会有重合部分,所以要最后画文字,用文字盖住重合的部分)      canvas.drawtext(progress + "%", currentmovedlentgh, textbottomy, painttext);    }       /**     * @param progress 外部传进来的当前进度     */    public void setprogress(int progress) {      this.progress = progress;      invalidate();    }  }

调用者activity的代码,设置进度条的进度:

  public class numberprogressbaractivity extends activity {       protected static final int what_increase = 1;    private numberprogressview np_numberprogressbar;    private int progress;       private handler handler = new handler() {      public void handlemessage(android.os.message msg) {        progress++;        np_numberprogressbar.setprogress(progress);        handler.sendemptymessagedelayed(what_increase, getradomnumber(50, 200));        if (progress >= 100) {          handler.removemessages(what_increase);        }      }    };       @override    protected void oncreate(bundle savedinstancestate) {      super.oncreate(savedinstancestate);      setcontentview(r.layout.activity_number_progress_bar);      np_numberprogressbar = (numberprogressview) findviewbyid(r.id.np_numberprogressbar);      button btn_numberprogressbar = (button) findviewbyid(r.id.btn_numberprogressbar);      btn_numberprogressbar.setonclicklistener(new onclicklistener() {        @override        public void onclick(view v) {          increase();        }      });    }       private void increase() {      progress = 0;      np_numberprogressbar.setprogress(0);      handler.removemessages(what_increase);      handler.sendemptymessage(what_increase);    }       /**     * 得到两个整数之间的一个随机数     *     * @param start 较小的数     * @param end  较大的数     * @return     */    public int getradomnumber(int start, int end) {      return (int) (start + math.random() * (end - start));    }  }

工具方法:

  /**     * 将dip或dp值转换为px值,保证尺寸大小不变     */    public static int dip2px(context context, float dipvalue) {      final float scale = context.getresources().getdisplaymetrics().density;      return (int) (dipvalue * scale + 0.5f);    }       /**     * 将sp值转换为px值,保证文字大小不变     */    public static int sp2px(context context, float spvalue) {      final float fontscale = context.getresources().getdisplaymetrics().scaleddensity;      return (int) (spvalue * fontscale + 0.5f);    }

布局:

  <linearlayout xmlns:android="https://schemas.android.com/apk/res/android"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:orientation="vertical">       <com.example.viewdemo.view.numberprogressview      android:id="@+id/np_numberprogressbar"      android:layout_width="wrap_content"      android:layout_height="100dp"      android:layout_margin="20dp"      android:background="#33890075"      />       <button      android:id="@+id/btn_numberprogressbar"      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:text="开始"/>     </linearlayout>

以上就是android开发分享Android自定义View实现水平带数字百分比进度条的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网(www.ctvol.com)!!>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/901922.html

(0)
上一篇 2021年10月24日
下一篇 2021年10月24日

精彩推荐