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

所属分类: 软件编程 / Android 阅读数: 40
收藏 0 赞 0 分享

使用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();
  }
 }
});

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

更多精彩内容其他人还在看

Android网络编程之获取网络上的Json数据实例

这篇文章主要介绍了Android网络编程之获取网络上的Json数据实例,本文用完整的代码实例讲解了在Android中读取网络中Json数据的方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Android网络编程之UDP通信模型实例

这篇文章主要介绍了Android网络编程之UDP通信模型实例,本文给出了服务端代码和客户端代码,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中使用ListView实现漂亮的表格效果

这篇文章主要介绍了Android中使用ListView实现漂亮的表格效果,本文用详细的代码实例创建了一个股票行情表格,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中刷新界面的二种方法

这篇文章主要介绍了Android中刷新界面的二种方法,本文使用Handler、postInvalidate两种方法实现界面刷新,需要的朋友可以参考下
收藏 0 赞 0 分享

Android SDK三种更新失败及其解决方法

这篇文章主要介绍了Android SDK三种更新失败及其解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(一)

Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代之的是提供anction bar来提供基本的用户功能
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(二)

这次将继续上一篇文章没有讲完的Menu的学习,上下文菜单(Context menu)和弹出菜单(Popup menu)
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(三)

今天继续昨天没有讲完的Menu的学习,主要是Popup Menu的学习,需要的朋友可以参考下
收藏 0 赞 0 分享

Android显示网络图片实例

这篇文章主要介绍了Android显示网络图片的方法,以实例形式展示了Android程序显示网络图片的方法,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多