Android自定义View 使用PathMeasure简单模仿系统ProgressBar(四)
使用pathmeasure简单模仿系统progressbar,效果如下:
还蛮像的吧,有的人问了,系统自带的你闲的搞这个干嘛,当然是纯粹为了学习pathmeasure这个类。
pathmeasure是用来测量path路径的,可以截取路径中某一段路径,通过改变这段路径的起点、终点,达到类似vectordrawable中的路径动画效果:
直接new就可以获得pathmeasure对象:
pathmeasure pathmeasure = new pathmeasure();
或者
pathmeasure pathmeasure = new pathmeasure(path, forceclosed);
其中path代表一个path对象,forceclosed代表你测量的path是否闭合,如果为true,那么测量长度的时候周长会按path.close()来算。
也可以调用以下方法设置路径:
pathmeasure.setpath(path, forceclosed);
获得路径的长度:
float length = pathmeasure.getlength();
截取路径,新截取到的赋值给一个新path对象mdstpath
pathmeasure.getsegment(start, stop, mdstpath, true);
其中start和stop为起止长度,第四个参数代表是否startwithmoveto,是否从moveto位置开始,一般为true。
要实现上面的效果,那就用属性动画写一个0到1的百分比,根据当前的百分比和原路径的长度,动态改变新路径的起止点长度:
1、写自定义属性、构造方法、初始化paint、path、测量宽高。注意path要两个,一个装有原始数据,一个去装新截取的路径数据:
mpath = new path(); mdst = new path();
2、初始化pathmeasure,并设置路径,获得原始长度:
@override protected void onsizechanged(int w, int h, int oldw, int oldh) { mpath.addcircle(w / 2, h / 2, mradius, path.direction.cw); mpathmeasure = new pathmeasure(); mpathmeasure.setpath(mpath, false); mpathlength = mpathmeasure.getlength(); }
因为给mpathmeasure 设置的路径必须要装载数据,所以此时mpath需要加上你想画的东西,画一个圆又要有宽高,ondraw中又不能new对象,所以我把这些操作放到了onsizechanged中。
3、写一个动画,获取当前长度的百分比mpathpercent:
private void startanim() { valueanimator anim = valueanimator.offloat(0, 1); anim.setinterpolator(new decelerateinterpolator()); anim.setrepeatcount(valueanimator.infinite); anim.setduration(manimduration); anim.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator animation) { mpathpercent = (float) animation.getanimatedvalue(); invalidate(); } }); anim.start(); //再加一个旋转动画以及两倍的时长,形成旋转视差 objectanimator animrotate = objectanimator.offloat(this, view.rotation, 0, 360); animrotate.setinterpolator(new linearinterpolator()); animrotate.setrepeatcount(valueanimator.infinite); animrotate.setduration(2 * manimduration); animrotate.start(); }
4、动态改变起止点长度,截取新路径并绘制:
@override protected void ondraw(canvas canvas) { float stop = mpathlength * mpathpercent; float start = (float) (stop - ((0.5 - math.abs(mpathpercent - 0.5)) * mpathlength * 4)); mdst.reset(); // mdst.lineto(0, 0); mpathmeasure.getsegment(start, stop, mdst, true); canvas.drawpath(mdst, mpaint); }
注意此时绘制的路径是新路径mdst,而不是装有原始数据的老路径mpath~
5、顺便加几个控制的方法:
public void start() { misloading = true; setvisibility(view.visible); startanim(); } public void stop() { misloading = false; setvisibility(view.gone); } public boolean isloading() { return misloading; }
button btn = (button) findviewbyid(r.id.btn); btn.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { if (loadingview.isloading()) { loadingview.stop(); } else { loadingview.start(); } } });
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。