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

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

12c06344a142c52a3b7d308f67f243e8.gif

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

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

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()方法,绘制圆、圆弧和百分比文本,注意坐标的计算:

36bc90e3379c61db914b6675a9dec809.png

@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:

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

android:layout_width="match_parent"

android:layout_height="match_parent">

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" />

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

}

});

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值