Animar la actualización de ProgressBar en Android

Estoy utilizando un ProgressBar en mi aplicación que actualizo en onProgressUpdate de un ASyncTask. Hasta aquí todo bien. Lo que quiero hacer es animar la actualización de progreso, por lo que no sólo "saltar" al valor, sino que se mueve sin problemas a ella.

He intentado hacerlo ejecutando el siguiente código:

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(); } } } }); 

El problema es que ProgressBar no actualiza su estado hasta que terminó su valor final (variable de progreso). Todos los estados intermedios no se muestran en la pantalla. Llamar a progressBar.invalidate () tampoco ayudó. ¿Algunas ideas? ¡Gracias!

He utilizado la animación de Android para esto:

 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); } } 

Y lo llaman así:

 ProgressBarAnimation anim = new ProgressBarAnimation(progress, from, to); anim.setDuration(1000); progress.startAnimation(anim); 

Nota: si desde y hacia el valor son demasiado bajos para producir una animación suave simplemente multiplíqueles por un 100 o así. Si lo hace, no olvide multiplicar setMax (…) también.

Utilizo un 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(); 

Esta es una versión mejorada de la solución @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); } } 

Y uso:

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

EDIT: Mientras mi respuesta funciona, respuesta de Eli Konkys es mejor. Utilícelo.

Si su hilo se ejecuta en el hilo de interfaz de usuario, debe entregar el hilo de interfaz de usuario para dar a las vistas una oportunidad para actualizar. Actualmente le indica a la barra de progreso "actualizar a 1, actualizar a 2, actualizar a 3" sin liberar nunca el hilo de interfaz de usuario para que realmente pueda actualizar.

La mejor manera de resolver este problema es utilizar Asynctask , tiene métodos nativos que se ejecutan tanto dentro como fuera del subproceso de la interfaz de usuario:

 public class MahClass extends AsyncTask<Void, Void, Void> { @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 puede parecer complicado al principio, pero es realmente eficiente para muchas tareas diferentes o como se especifica en la API de Android:

"AsyncTask permite el uso adecuado y fácil del subproceso de la interfaz de usuario. Esta clase permite realizar operaciones en segundo plano y publicar resultados en el subproceso de interfaz de usuario sin tener que manipular subprocesos y / o controladores".

Usted podría intentar utilizar un manejador / runnable en su lugar …

 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); 

Esta es una versión mejorada de a.ch. Donde también se puede utilizar la rotación para ProgressBar circular. A veces es necesario establecer un progreso constante y cambiar sólo la rotación o incluso el progreso y la rotación. También es posible forzar la rotación en sentido horario o antihorario. Espero que ayude.

 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); } } } 

Uso:

 ProgressBarAnimation progressBarAnimation = new ProgressBarAnimation(progressBar, 1000); // Example 1 progressBarAnimation.setProgressAndRotation(newProgress, newRotation); // Example 2 progressBarAnimation.setProgressOnly(newProgress); // Example 3 progressBarAnimation.setRotationOnly(newRotation); 
  • ¿Cómo aplicar gradiente a la barra de estado en android?
  • Cómo crear una aplicación para tablets y dispositivos móviles
  • Cómo implementar una superposición emergente que se puede mostrar sobre cualquier otra aplicación en Android
  • Ajuste del tamaño de los botones en porcentaje
  • ¿Cómo mostrar más de 3 niveles de Vista de lista expandible?
  • Color de fondo del texto de Android TextView
  • Implementación de las directrices de diseño de Google para Sliders
  • ¿Por qué deberíamos usar sp para tamaños de fuente en Android?
  • Cómo configurar el encabezado y el pie de página en android?
  • Frente a View.bringToFront () en Android
  • ¿Cómo puedo ejecutar el código en el hilo de la interfaz de usuario en una prueba de Android JUnit sin una actividad?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.