当前位置: 移动技术网 > IT编程>移动开发>Android > Android view自定义实现动态进度条

Android view自定义实现动态进度条

2019年07月24日  | 移动技术网IT编程  | 我要评论

上海展会设计,农产品供求信息,朴元浩

android  自定义view实现动态进度条

效果图:

这里写图片描述

这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧、顶部、右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这个过程还是有点曲折的,不过还是觉得收获挺多的。比如通动画来进行动态的展示(之前做的都是通过handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画部分就可以了。不多说了,上代码了。

代码

自定义view

public class colorprogressbar extends view{
  //下面这两行在本demo中没什么用,只是前几天看别人的代码时学到的按一定尺寸,设置其他尺寸的方式,自动忽略或者学习一下也不错
//  private int defaultstepindicatornum= (int) typedvalue.applydimension(typedvalue.complex_unit_dip,40,getresources().getdisplaymetrics());
//  int mcircleradius=0.28f*defaultstepindicatornum;


  //布局的宽高
  private int mwidth;
  private int mheight;
  //直径
  private int mdiameter=500;

  //底层圆画笔
  private paint mpaintbg;
  //顶层圆的画笔
  private paint mpaintft;
  //周围线的画笔
  private paint mpaintline;

  //外层线条的长度
  private int mlongitem=dip2px(20);
  //线条与圆的间距
  private int mdistanceitem=dip2px(10);
  //进度条的最大宽度(取底层进度条与顶层进度条宽度最大的)
  private int mprogresswidth;

  //底层圆的颜色
  private int mbackcolor;
  //顶层圆的颜色
  private int mfrontcolor;
  //底层圆、顶层圆的宽度
  private float mbackwidth;
  private float mfrontwidth;
  //设置进度
  private float currentvalue;
  //通过动画演示进度
  private valueanimator animator;
  private int curvalue;



  public colorprogressbar(context context) {
    this(context,null,0);
  }

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

  public colorprogressbar(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    typedarray ta=context.obtainstyledattributes(attrs, r.styleable.colorprogressbar);
    mbackcolor= ta.getcolor(r.styleable.colorprogressbar_back_color, color.black);
    mfrontcolor=ta.getcolor(r.styleable.colorprogressbar_front_color,mbackcolor);
    mbackwidth=ta.getdimension(r.styleable.colorprogressbar_back_width,dip2px(10));
    mfrontwidth=ta.getdimension(r.styleable.colorprogressbar_front_width,dip2px(10));
    mprogresswidth=mbackwidth>mfrontwidth?(int)mbackwidth:(int)mfrontwidth;
    //注意释放资源
    ta.recycle();
    init();
  }

  /**
   * 都是画笔初始化
   */
  private void init() {
    mpaintbg=new paint(paint.anti_alias_flag);
    mpaintbg.setstrokewidth(mprogresswidth);
    mpaintbg.setcolor(mbackcolor);
    mpaintbg.setstrokecap(paint.cap.round);
    mpaintbg.setstyle(paint.style.stroke);

    mpaintft=new paint(paint.anti_alias_flag);
    mpaintft.setcolor(mfrontcolor);
    mpaintft.setstyle(paint.style.stroke);
    mpaintft.setstrokewidth(mfrontwidth);
    mpaintft.setstrokecap(paint.cap.round);

    mpaintline=new paint(paint.anti_alias_flag);
    mpaintline.setcolor(color.black);
    mpaintline.setstrokewidth(5);

  }

  @override
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    super.onmeasure(widthmeasurespec, heightmeasurespec);
//   宽度=高度=(长指针+指针与圆盘的间距+进度条的粗细+半径)*2
    log.e("测量数据","longitem:"+mlongitem+"mdistanceitem:"+mdistanceitem+"mprogresswidth:"+mprogresswidth+"mdiameter:"+mdiameter/2);
    mwidth=(int)2*(mlongitem+mdistanceitem+mprogresswidth*2+mdiameter/2);
    mheight=(int)2*(mlongitem+mdistanceitem+mprogresswidth*2+mdiameter/2);
    log.e("自定义view","高度"+mheight+"宽度"+mwidth);
    setmeasureddimension(mwidth,mheight);
  }


  @override
  protected void ondraw(canvas canvas) {
    super.ondraw(canvas);
    //绘制底层圆弧,矩形的具体计算见图片
    canvas.drawarc(new rectf(mprogresswidth/2+mdistanceitem+mlongitem,mprogresswidth/2+mdistanceitem+mlongitem,mwidth-mprogresswidth/2-mdistanceitem-mlongitem,mheight-mprogresswidth/2-mdistanceitem-mlongitem),0,360,true,mpaintbg);
//    sweepgradient gradient=new sweepgradient();
    //绘制边缘线
    canvas.save();
    canvas.rotate(144,mwidth/2,mheight/2);
    for(int i=0;i<=30;i++){
      canvas.rotate(-9,mwidth/2,mheight/2);
      if(i%5==0){
        canvas.drawline(mwidth/2,5,mwidth/2,mlongitem,mpaintbg);
      }else {
        canvas.drawline(mwidth/2,25,mwidth/2,mlongitem,mpaintline);
      }
    }

    canvas.restore();
    //给画笔设置渐变
    sweepgradient sweepgradient=new sweepgradient(mwidth/2,mheight/2,color.red,color.yellow);
    mpaintft.setshader(sweepgradient);
    //绘制顶层圆弧,currentvalue在改变时呈现动态效果
    canvas.drawarc(new rectf(mprogresswidth/2+mdistanceitem+mlongitem,mprogresswidth/2+mdistanceitem+mlongitem,mwidth-mprogresswidth/2-mdistanceitem-mlongitem,mheight-mprogresswidth/2-mdistanceitem-mlongitem),135,currentvalue,false,mpaintft);
    mpaintft.settextsize(100);
    mpaintft.settextalign(paint.align.center);
    //绘制文本
    canvas.drawtext(string.format("%.0f",currentvalue),mwidth/2,mheight/2+50,mpaintft);
    invalidate();
  }

  /**
   * 设置动画
   * @param value
   */
  public void setcurrentvalue(float value){
//    currentvalue=value;
    animator=valueanimator.offloat(currentvalue,value);
    animator.setduration(3000);
    animator.settarget(currentvalue);
    animator.addupdatelistener(new valueanimator.animatorupdatelistener() {
      @override
      public void onanimationupdate(valueanimator valueanimator) {
        currentvalue= (float) valueanimator.getanimatedvalue();
        curvalue=curvalue/10;
      }
    });
    animator.start();

  }
  private int dip2px(float dip){
    float density=getcontext().getresources().getdisplaymetrics().density;
    return (int)(dip*density+0.5f);
  }
}

矩形计算

这里写图片描述

activity调用

 @override
  protected void oncreate(@nullable bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.colorprogressbar);
    mbtstart1= (button) findviewbyid(r.id.bt1);

    bar1= (colorprogressbar) findviewbyid(r.id.cp1);

    mbtstart1.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view view) {
        bar1.setcurrentvalue(270);
      }
    });

  }

自定义属性

 <declare-styleable name="colorprogressbar">
    <attr name="back_color" format="color"></attr>
    <attr name="front_color" format="color"></attr>
    <attr name="back_width" format="dimension"></attr>
    <attr name="front_width" format="dimension"></attr>
  </declare-styleable>

布局

注意:为了使用自定义属性需要添加一行代码(as)

xmlns:app=http://schemas.android.com/apk/res-auto

布局

<linearlayout
 xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <button
      android:id="@+id/bt1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="start1"/>

    <com.demo.demo.networkdemo.colorprogressbar.widget.colorprogressbar
      android:id="@+id/cp1"
      android:layout_width="232dp"
      android:layout_height="match_parent"
      android:layout_gravity="center_horizontal"
      app:back_color="@color/colorprimary"
      app:front_color="@color/coloraccent"
      android:background="@mipmap/ic_launcher"/>


  </linearlayout>

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网