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

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

程序员文章站 2024-02-24 23:50:52
android  自定义view实现动态进度条 效果图: 这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从...

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

效果图:

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);
  }
}

矩形计算

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

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>

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