Подтвердить что ты не робот

Обновите обновление ProgressBar

Я использую индикатор выполнения (в виде бара). Я хочу, чтобы бар увеличивался и плавно менялся с помощью интерполятора, но он не работает. Это то, что у меня есть на данный момент:

pb.setInterpolator(main.this, android.R.anim.bounce_interpolator);             
pb.setProgress(pb.getProgress()+10);

Я делаю что-то действительно не так?

4b9b3361

Ответ 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 (..).