我正在使用进度条 (以条形形式显示)。我希望使用插值器使进度条平滑地增加和减少,但它不起作用。目前我的代码如下:
pb.setInterpolator(main.this, android.R.anim.bounce_interpolator);
pb.setProgress(pb.getProgress()+10);
我是否在做一些非常错误的事情?
我正在使用进度条 (以条形形式显示)。我希望使用插值器使进度条平滑地增加和减少,但它不起作用。目前我的代码如下:
pb.setInterpolator(main.this, android.R.anim.bounce_interpolator);
pb.setProgress(pb.getProgress()+10);
我是否在做一些非常错误的事情?
插值器必须附加到动画上,而且仅在Honeycomb或更高版本上才能使用:
if(android.os.Build.VERSION.SDK_INT >= 11){
// will update the "progress" propriety of seekbar until it reaches progress
ObjectAnimator animation = ObjectAnimator.ofInt(seekbar, "progress", progress);
animation.setDuration(500); // 0.5 second
animation.setInterpolator(new DecelerateInterpolator());
animation.start();
}
else
seekbar.setProgress(progress); // no animation on Gingerbread or lower
如果您的最低SDK版本是Gingerbread或更低版本,请添加:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
// or
@SuppressLint("NewApi")
传递给你的函数/类。
我使用了DecelerateInterpolator,但这是可选的,还有其他可能性。
animation.setInterpolator(new LinearInterpolator());
来设置动画插值器。 - offset这里提供了一个自包含的解决方案:
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.ProgressBar;
public class AnimatingProgressBar extends ProgressBar {
private static final Interpolator DEFAULT_INTERPOLATER = new AccelerateDecelerateInterpolator();
private ValueAnimator animator;
private ValueAnimator animatorSecondary;
private boolean animate = true;
public AnimatingProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public AnimatingProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AnimatingProgressBar(Context context) {
super(context);
}
public boolean isAnimate() {
return animate;
}
public void setAnimate(boolean animate) {
this.animate = animate;
}
@Override
public synchronized void setProgress(int progress) {
if (!animate) {
super.setProgress(progress);
return;
}
if (animator != null)
animator.cancel();
if (animator == null) {
animator = ValueAnimator.ofInt(getProgress(), progress);
animator.setInterpolator(DEFAULT_INTERPOLATER);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
AnimatingProgressBar.super.setProgress((Integer) animation.getAnimatedValue());
}
});
} else
animator.setIntValues(getProgress(), progress);
animator.start();
}
@Override
public synchronized void setSecondaryProgress(int secondaryProgress) {
if (!animate) {
super.setSecondaryProgress(secondaryProgress);
return;
}
if (animatorSecondary != null)
animatorSecondary.cancel();
if (animatorSecondary == null) {
animatorSecondary = ValueAnimator.ofInt(getProgress(), secondaryProgress);
animatorSecondary.setInterpolator(DEFAULT_INTERPOLATER);
animatorSecondary.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
AnimatingProgressBar.super.setSecondaryProgress((Integer) animation
.getAnimatedValue());
}
});
} else
animatorSecondary.setIntValues(getProgress(), secondaryProgress);
animatorSecondary.start();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (animator != null)
animator.cancel();
if (animatorSecondary != null)
animatorSecondary.cancel();
}
}
在您的布局中使用 AnimatingProgressBar
替换 ProgressBar
您还可以将类型更改为 AnimatingProgressBar,以利用 setAnimate()
禁用动画(在恢复活动状态时可能很有用)
如果每次将进度值增加1(例如从45变为46),则不会看到动画效果。最好每次以100个点的方式更改进度,为此只需将最大值乘以100,每个进度值也乘以100即可。例如:
private void setProgressMax(ProgressBar pb, int max) {
pb.setMax(max * 100);
}
private void setProgressAnimate(ProgressBar pb, int progressTo)
{
ObjectAnimator animation = ObjectAnimator.ofInt(pb, "progress", pb.getProgress(), progressTo * 100);
animation.setDuration(500);
animation.setInterpolator(new DecelerateInterpolator());
animation.start();
}
我找到了一种方法来实现它,通过使用一个可运行的程序,我能够每秒更新进度条多次,从而产生滑动效果。以下是代码:
private Runnable SmoothIncrement = new Runnable() {
public void run() {
final long start = mStartTime;
long millis = SystemClock.uptimeMillis() - start;
if(track!=increase) {
if((pb.getProgress()==100)&&(count<target)) {
pb.setProgress(0);
}
pb.incrementProgressBy(1);
track++;
incrementor.postAtTime(this, start + millis);
}
else {
incrementor.removeCallbacks(this);
}
}
};
这里,'track' 跟踪了已经完成的增量数量,而 'increase' 是应该完成的总增量数。我可以从 UI 线程动态增加增量的数量,以获得平滑的效果。该代码仅适用于不需要减少的进度条。
要运行它,只需使用以下代码:
mStartTime = System.currentTimeMillis();
incrementor.removeCallbacks(SmoothIncrement);
if(track!=0) {
track -= increase;
}
incrementor.postDelayed(SmoothIncrement, 0);
incrementor
是什么类型的对象,以及它如何应用于ProgressBar吗?我也在寻找这个解决方案。谢谢。 - midhunhkpb.setProgress(pb.getProgress() * 100);
根据文档,插值器适用于不确定的进度。由于您设置了进度,我认为您打算使用具有值的常规进度。我认为对您来说最好的方法是增加进度的最大值并以较小的增量进行操作。