Обновите обновление ProgressBar
Я использую индикатор выполнения (в виде бара). Я хочу, чтобы бар увеличивался и плавно менялся с помощью интерполятора, но он не работает. Это то, что у меня есть на данный момент:
pb.setInterpolator(main.this, android.R.anim.bounce_interpolator);
pb.setProgress(pb.getProgress()+10);
Я делаю что-то действительно не так?
Ответы
Ответ 1
Интерполятор должен быть привязан к анимации, и это будет работать только на сотах или выше:
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, но это необязательно, и есть другие возможности.
Ответ 2
Вот самодостаточное решение:
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();
}
}
замените ProgressBar
на AnimatingProgressBar
в вашем макете
Вы также меняете тип AnimatingProgressBar на использование setAnimate()
для отключения анимации (может быть полезно при восстановлении состояния активности)
Ответ 3
Если вы изменяете значение прогресса каждый раз на 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();
}
Ответ 4
Я разработал, как это сделать, используя runnable, я смог обновить индикатор выполнения несколько раз в секунду и, таким образом, дать эффект скольжения. Код ниже:
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" отслеживает, сколько приращений было сделано, а увеличение - общее количество шагов, которые должны быть сделаны. Я могу динамически увеличивать количество приращений из потока пользовательского интерфейса, чтобы обеспечить плавный эффект. Код работает только для индикаторов выполнения, которые не нуждаются в уменьшении.
Чтобы запустить его, просто используйте этот код:
mStartTime = System.currentTimeMillis();
incrementor.removeCallbacks(SmoothIncrement);
if(track!=0) {
track -= increase;
}
incrementor.postDelayed(SmoothIncrement, 0);
Ответ 5
Моя библиотека Link
Над ссылкой находится моя библиотека.
Просто используйте его, если хотите.
Ответ 6
Я не уверен, но, пожалуйста, проверьте его:
pb.setProgress(pb.getProgress() * 100);
Ответ 7
В соответствии с документацией интерполятор применяется к неопределенному прогрессу.
Поскольку вы устанавливаете прогресс, я думаю, вы намереваетесь использовать обычный со значениями.
Я думаю, что для вас лучше всего было бы увеличить максимальную ценность прогресса и
идти меньшими приращениями.
Ответ 8
Я использовал анимацию для Android:
public class ProgressBarAnimation extends Animation{
private ProgressBar progressBar;
private float from;
private float to;
public ProgressBarAnimation(ProgressBar progressBar, float from, float to) {
super();
this.progressBar = progressBar;
this.from = from;
this.to = to;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float value = from + (to - from) * interpolatedTime;
progressBar.setProgress((int) value);
}
}
и назовите его так:
ProgressBarAnimation anim = new ProgressBarAnimation(progress, from, to);
anim.setDuration(1000);
progress.startAnimation(anim);
Примечание: если из и для значения слишком низкие, чтобы создать гладкую анимацию, просто умножьте их на 100 или около того. Если вы это сделаете, не забудьте также умножить setMax (..).