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();
}
}
});
您可能感兴趣的文章:Android自定义谷歌风格ProgressBarAndroid编程实现自定义ProgressBar样式示例(背景色及一级、二级进度条颜色)Android三种方式实现ProgressBar自定义圆形进度条Android编程ProgressBar自定义样式之动画模式实现方法android ListView和ProgressBar(进度条控件)的使用方法Android ProgressBar进度条和ProgressDialog进度框的展示DEMOAndroid ProgressBar进度条使用详解Android编程之自定义ProgressBar示例
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341