做一个自定义view的小练习,效果如下
只需要画一个圆、一个圆弧、一个百分比文本,添加一个点击事件,传入百分比重绘
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()方法,绘制圆、圆弧和百分比文本,注意坐标的计算:
@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);
}
});
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。