当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义View圆形百分比控件(一)

Android自定义View圆形百分比控件(一)

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

精美散文阅读,sxzq,奈瑟匹拉

做一个自定义view的小练习,效果如下

这里写图片描述

只需要画一个圆、一个圆弧、一个百分比文本,添加一个点击事件,传入百分比重绘

1、在res/values文件夹下新建attrs.xml文件,编写自定义属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="circlepercentview" >
    <attr name="circlebg" format="color"/>
    <attr name="arccolor" format="color"/>
    <attr name="arcwidth" format="dimension"/>
    <attr name="percenttextcolor" format="color"/>
    <attr name="percenttextsize" format="dimension"/>
    <attr name="radius" format="dimension"/>
  </declare-styleable>
</resources>

2、新建circlepercentview继承view,重写构造方法:

public circlepercentview(context context) {
    this(context, null);
  }

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

  public circlepercentview(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
  }

3、在第三个构造方法中获取自定义属性的值:

    typedarray ta = context.obtainstyledattributes(attrs, r.styleable.circlepercentview, defstyleattr, 0);
    mcirclecolor = ta.getcolor(r.styleable.circlepercentview_circlebg, 0xff8e29fa);
    marccolor = ta.getcolor(r.styleable.circlepercentview_arccolor, 0xffffee00);
    marcwidth = ta.getdimensionpixelsize(r.styleable.circlepercentview_arcwidth, densityutils.dp2px(context, 16));
    mpercenttextcolor = ta.getcolor(r.styleable.circlepercentview_arccolor, 0xffffee00);
    mpercenttextsize = ta.getdimensionpixelsize(r.styleable.circlepercentview_percenttextsize, densityutils.sp2px(context, 16));
    mradius = ta.getdimensionpixelsize(r.styleable.circlepercentview_radius, densityutils.dp2px(context, 100));
    ta.recycle();

4、创建画图所使用的对象,如paint、rect、rectf:

    mcirclepaint = new paint(paint.anti_alias_flag);
    mcirclepaint.setstyle(paint.style.fill);
    mcirclepaint.setcolor(mcirclecolor);

    marcpaint = new paint(paint.anti_alias_flag);
    marcpaint.setstyle(paint.style.stroke);
    marcpaint.setstrokewidth(marcwidth);
    marcpaint.setcolor(marccolor);
    marcpaint.setstrokecap(paint.cap.round);//使圆弧两头圆滑

    mpercenttextpaint = new paint(paint.anti_alias_flag);
    mpercenttextpaint.setstyle(paint.style.stroke);
    mpercenttextpaint.setcolor(mpercenttextcolor);
    mpercenttextpaint.settextsize(mpercenttextsize);

    marcrectf = new rectf();//圆弧的外接矩形

    mtextbound = new rect();//文本的范围矩形

5、重写onmeasure()方法,计算自定义view的宽高:

 @override
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    setmeasureddimension(measuredimension(widthmeasurespec), measuredimension(heightmeasurespec));
  }

  private int measuredimension(int measurespec) {
    int result;
    int specmode = measurespec.getmode(measurespec);
    int specsize = measurespec.getsize(measurespec);
    if (specmode == measurespec.exactly) {//精确地,代表宽高为定值或者match_parent时
      result = specsize;
    } else {
      result = 2 * mradius;
      if (specmode == measurespec.at_most) {//最大地,代表宽高为wrap_content时
        result = math.min(result, specsize);
      }
    }
    return result;
  }

6、重写ondraw()方法,绘制圆、圆弧和百分比文本,注意坐标的计算:

这里写图片描述

  @override
  protected void ondraw(canvas canvas) {
    //画圆
    canvas.drawcircle(getwidth() / 2, getheight() / 2, mradius, mcirclepaint);

    //画圆弧
    marcrectf.set(getwidth() / 2 - mradius + marcwidth / 2, getheight() / 2 - mradius + marcwidth / 2
        , getwidth() / 2 + mradius - marcwidth / 2, getheight() / 2 + mradius - marcwidth / 2);
    canvas.drawarc(marcrectf, 270, 360 * mcurpercent / 100, false, marcpaint);

    string text = mcurpercent + "%";
    //计算文本宽高
    mpercenttextpaint.gettextbounds(text, 0, string.valueof(text).length(), mtextbound);
    //画百分比文本
    canvas.drawtext(text, getwidth() / 2 - mtextbound.width() / 2
        , getheight() / 2 + mtextbound.height() / 2, mpercenttextpaint);
  }

7、给这个view设置点击事件,暴露一个动态设置百分比的方法:

  public void setcurpercent(float curpercent) {
    valueanimator anim = valueanimator.offloat(mcurpercent, curpercent);
    //动画时长由百分比大小决定
    anim.setduration((long) (math.abs(mcurpercent - curpercent) * 20));
    anim.addupdatelistener(new valueanimator.animatorupdatelistener() {
      @override
      public void onanimationupdate(valueanimator animation) {
        float value = (float) animation.getanimatedvalue();
        mcurpercent = (float) (math.round(value * 10)) / 10;//四舍五入保留到小数点后两位
        invalidate();//重绘,重走ondraw()方法,这也是不能再ondraw()中创建对象的原因
      }
    });
    anim.start();
  }

  public void setoncircleclicklistener(onclicklistener onclicklistener) {
    this.monclicklistener = onclicklistener;
  }

    //在构造方法中
    setonclicklistener(new onclicklistener() {
      @override
      public void onclick(view v) {
        if (monclicklistener != null) {
          monclicklistener.onclick(circlepercentview.this);
        }
      }
    });

8、在activity_main.xml布局文件中使用该view:

<!-- 使用自定义命名空间namespace,cpv是该控件名的首字母缩写,可以随意取 -->
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:cpv="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <!-- cpv后面的属性名对应attrs.xml文件中的自定义属性名 -->
  <com.monkey.customviewdemo.view.circlepercentview
    android:id="@+id/circlepercentview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    cpv:arccolor="#ffee00"
    cpv:arcwidth="@dimen/activity_horizontal_margin"
    cpv:circlebg="#8e29fa"
    cpv:percenttextcolor="#ffee00"
    cpv:percenttextsize="16sp"
    cpv:radius="100dp" />
</relativelayout>

9、在mainactivity.java中设置监听,传入百分比:

  mcirclepercentview = (circlepercentview) findviewbyid(r.id.circlepercentview);
  mcirclepercentview.setoncircleclicklistener(new view.onclicklistener() {
    @override
    public void onclick(view v) {
      float percent = (float) (math.random() * 99 + 1);
      mcirclepercentview.setcurpercent(percent);
    }
  });


代码下载地址:
https://github.com/monkeymushroom/circlepercentview/tree/master

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

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

相关文章:

验证码:
移动技术网