Анимировать обновление ProgressBar в Android

Я использую ProgressBar в своем приложении, которое я обновляю в onProgressUpdate для ASyncTask. Все идет нормально. То, что я хочу сделать, – это оживить обновление прогресса, чтобы он не просто «прыгал» на значение, а плавно переходил к нему.

Я попытался сделать следующий код:

this.runOnUiThread(new Runnable() { @Override public void run() { while (progressBar.getProgress() < progress) { progressBar.incrementProgressBy(1); progressBar.invalidate(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); 

Проблема в том, что ProgressBar не обновляет свое состояние до тех пор, пока не завершит свое окончательное значение (переменная прогресса). Все состояния между ними не отображаются на экране. Вызов progressBar.invalidate () тоже не помог. Есть идеи? Благодаря!

    Я использовал анимацию для 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 (..).

    Я использую ObjectAnimator

     private ProgressBar progreso; private ObjectAnimator progressAnimator; progreso = (ProgressBar)findViewById(R.id.progressbar1); progressAnimator = ObjectAnimator.ofFloat(progreso, "progress", 0.0f,1.0f); progressAnimator.setDuration(7000); progressAnimator.start(); 

    Вот улучшенная версия решения @Eli Konky :

     public class ProgressBarAnimation extends Animation { private ProgressBar mProgressBar; private int mTo; private int mFrom; private long mStepDuration; /** * @param fullDuration - time required to fill progress from 0% to 100% */ public ProgressBarAnimation(ProgressBar progressBar, long fullDuration) { super(); mProgressBar = progressBar; mStepDuration = fullDuration / progressBar.getMax(); } public void setProgress(int progress) { if (progress < 0) { progress = 0; } if (progress > mProgressBar.getMax()) { progress = mProgressBar.getMax(); } mTo = progress; mFrom = mProgressBar.getProgress(); setDuration(Math.abs(mTo - mFrom) * mStepDuration); mProgressBar.startAnimation(this); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { float value = mFrom + (mTo - mFrom) * interpolatedTime; mProgressBar.setProgress((int) value); } } 

    И использование:

     ProgressBarAnimation mProgressAnimation = new ProgressBarAnimation(mProgressBar, 1000); ... /* Update progress later anywhere in code: */ mProgressAnimation.setProgress(progress); 

    EDIT: Хотя мой ответ работает, ответ Eli Konkys лучше. Используй это.

    если ваш stream работает в streamе пользовательского интерфейса, он должен сдать stream пользовательского интерфейса, чтобы дать возможность просмотра. В настоящее время вы указываете индикатор выполнения «обновление до 1, обновление до 2, обновление до 3», не отпуская ни одного пользовательского интерфейса, чтобы он действительно мог обновляться.

    Лучший способ решить эту проблему – использовать Asynctask , у нее есть встроенные методы, которые запускаются как внутри , так и вне streamа пользовательского интерфейса:

     public class MahClass extends AsyncTask { @Override protected Void doInBackground(Void... params) { while (progressBar.getProgress() < progress) { publishProgress(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Void... values) { progressBar.incrementProgressBy(1); } } 

    AsyncTask может показаться сложным сначала, но он действительно эффективен для многих разных задач или, как указано в Android API:

    «AsyncTask позволяет правильно и просто использовать stream пользовательского интерфейса. Этот class позволяет выполнять фоновые операции и публиковать результаты в streamе пользовательского интерфейса без необходимости манипулировать streamами и / или обработчиками».

    Вместо этого вы можете попробовать использовать обработчик / runnable …

     private Handler h = new Handler(); private Runnable myRunnable = new Runnable() { public void run() { if (progressBar.getProgress() < progress) { progressBar.incrementProgressBy(1); progressBar.invalidate(); h.postDelayed(myRunnable, 10); //run again after 10 ms } }; //trigger runnable in your code h.postDelayed(myRunnable, 10); //don't forget to cancel runnable when you reach 100% h.removeCallbacks(myRunnable); 

    Вот улучшенная версия a.ch. где вы также можете использовать поворот для кругового ProgressBar. Иногда требуется установить постоянный прогресс и изменить только rotation или даже прогресс и rotation. Также возможно принудительное rotation по часовой стрелке или против часовой стрелки. Надеюсь, это поможет.

     public class ProgressBarAnimation extends Animation { private ProgressBar progressBar; private int progressTo; private int progressFrom; private float rotationTo; private float rotationFrom; private long animationDuration; private boolean forceClockwiseRotation; private boolean forceCounterClockwiseRotation; /** * Default constructor * @param progressBar ProgressBar object * @param fullDuration - time required to change progress/rotation */ public ProgressBarAnimation(ProgressBar progressBar, long fullDuration) { super(); this.progressBar = progressBar; animationDuration = fullDuration; forceClockwiseRotation = false; forceCounterClockwiseRotation = false; } /** * Method for forcing clockwise rotation for progress bar * Method also disables forcing counter clockwise rotation * @param forceClockwiseRotation true if should force clockwise rotation for progress bar */ public void forceClockwiseRotation(boolean forceClockwiseRotation) { this.forceClockwiseRotation = forceClockwiseRotation; if (forceClockwiseRotation && forceCounterClockwiseRotation) { // Can't force counter clockwise and clockwise rotation in the same time forceCounterClockwiseRotation = false; } } /** * Method for forcing counter clockwise rotation for progress bar * Method also disables forcing clockwise rotation * @param forceCounterClockwiseRotation true if should force counter clockwise rotation for progress bar */ public void forceCounterClockwiseRotation(boolean forceCounterClockwiseRotation) { this.forceCounterClockwiseRotation = forceCounterClockwiseRotation; if (forceCounterClockwiseRotation && forceClockwiseRotation) { // Can't force counter clockwise and clockwise rotation in the same time forceClockwiseRotation = false; } } /** * Method for setting new progress and rotation * @param progress new progress * @param rotation new rotation */ public void setProgressAndRotation(int progress, float rotation) { if (progressBar != null) { // New progress must be between 0 and max if (progress < 0) { progress = 0; } if (progress > progressBar.getMax()) { progress = progressBar.getMax(); } progressTo = progress; // Rotation value should be between 0 and 360 rotationTo = rotation % 360; // Current rotation value should be between 0 and 360 if (progressBar.getRotation() < 0) { progressBar.setRotation(progressBar.getRotation() + 360); } progressBar.setRotation(progressBar.getRotation() % 360); progressFrom = progressBar.getProgress(); rotationFrom = progressBar.getRotation(); // Check for clockwise rotation if (forceClockwiseRotation && rotationTo < rotationFrom) { rotationTo += 360; } // Check for counter clockwise rotation if (forceCounterClockwiseRotation && rotationTo > rotationFrom) { rotationTo -= 360; } setDuration(animationDuration); progressBar.startAnimation(this); } } /** * Method for setting only progress for progress bar * @param progress new progress */ public void setProgressOnly(int progress) { if (progressBar != null) { setProgressAndRotation(progress, progressBar.getRotation()); } } /** * Method for setting only rotation for progress bar * @param rotation new rotation */ public void setRotationOnly(float rotation) { if (progressBar != null) { setProgressAndRotation(progressBar.getProgress(), rotation); } } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { float progress = progressFrom + (progressTo - progressFrom) * interpolatedTime; float rotation = rotationFrom + (rotationTo - rotationFrom) * interpolatedTime; // Set new progress and rotation if (progressBar != null) { progressBar.setProgress((int) progress); progressBar.setRotation(rotation); } } } 

    Применение:

     ProgressBarAnimation progressBarAnimation = new ProgressBarAnimation(progressBar, 1000); // Example 1 progressBarAnimation.setProgressAndRotation(newProgress, newRotation); // Example 2 progressBarAnimation.setProgressOnly(newProgress); // Example 3 progressBarAnimation.setRotationOnly(newRotation); 
    Interesting Posts

    Hibernate: MyInterceptor # onFlushDirty никогда не вызывается

    Исключить ошибку сегментации записи в shellcode

    Как я могу отложить вызов метода на 1 секунду?

    bds 2006 C конфликты с скрытым диспетчером памяти (class new / delete vs. AnsiString)

    Проблема maven-archetype-webapp eclipse

    Параметры querystring безопасны в HTTPS (HTTP + SSL)?

    Кто-нибудь действительно эффективно реализовал Fibonacci-Heap?

    Избегайте ввода пароля для ключей и подсказок для информации о DN

    $ (document) .on («click» … не работает?

    Содержит ли соединение сокетов TCP «поддерживать»?

    Почему я получаю ошибку «sqlite3: not found» на внедренном Nexus One при попытке открыть базу данных с помощью оболочки adb?

    MATLAB находит и применяет функцию к значениям повторяющихся индексов

    Почему удаленный рабочий стол (RDP) недостаточно быстрый для просмотра видео на удаленном ПК?

    Лучший способ обнаружить выпускную сборку из сборки отладки? .сеть

    Визуализация AST, созданного с помощью ANTLR (в среде .NET)

    Давайте будем гением компьютера.