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

Android自定义View 使用PathMeasure简单模仿系统ProgressBar(四)

程序员文章站 2023-11-17 12:33:16
使用pathmeasure简单模仿系统progressbar,效果如下: 还蛮像的吧,有的人问了,系统自带的你闲的搞这个干嘛,当然是纯粹为了学习pathmeasure...

使用pathmeasure简单模仿系统progressbar,效果如下:

Android自定义View 使用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();
  }
 }
});

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