Modificación de la imagen de recurso de la barra de progreso

Quiero crear una barra de progreso para Android. Tengo cuatro imágenes para mi barra de progreso cuadrada.

Estoy usando la barra de progreso definida para Android:

<ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" style="@android:style/Widget.ProgressBar.Small" android:layout_marginRight="5dp" /> 

Pero si quiero hacer un cuadrado en lugar del círculo, ¿cómo puedo hacerlo? ¿Cómo paso mis 4 imágenes a la barra de progreso?

ejemplo:

Introduzca aquí la descripción de la imagen

Generalmente usted tiene 2 opciones :

1. Como ya se mencionó, utilice una animation-list y simplemente intercambiar imágenes.

Esta es probablemente la solución más fácil, ya que pueden ser relativamente fáciles de animar con AnimationDrawable . El único inconveniente sería que necesitas al menos 16 imágenes (en todas las resoluciones) para el resultado dado.

2. Utilizar un dibujable personalizado.

Este es el enfoque más complicado. Usted tendrá que hacer el dibujo y animarse a sí mismo, que es una tarea difícil para la mayoría de la gente con poca documentación buena.

Por lo tanto, tiene que extends Drawable implements Runnable, Animatable y proporcionar algunas implementaciones buenas.

Lo siguiente es una impelmentación básica, calculando las posiciones una vez, luego dibujándolas. La animación (el tamaño de los círculos individuales) puede y debe ser más ajustado;)

Resultado en 3 variantes:
Barras Progree

 public class RectProgressDrawable extends Drawable implements Runnable, Animatable { private static final long FRAME_DELAY = 1000 / 60; private static final String TAG = "RectProgressDrawable"; private boolean mRunning = false; private long mStartTime; private int mDuration = 1000; private Paint mPaint; private float[] posX; private float[] posY; private float mSize; private int mPoints = 5; /** * The padding in px. */ private int mPadding = 4; private int mAnimatedPoints = 5; public void setPoints(int points) { if (points != mPoints) { mPoints = points; init(); } } private void init() { if (mPaint == null) { mPaint = new Paint(); mPaint.setColor(Color.WHITE); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); } posX = new float[(mPoints - 1) * 4]; posY = new float[(mPoints - 1) * 4]; Rect bounds = new Rect(); bounds.set(getBounds()); bounds.inset(mPadding, mPadding); float cellWidth = ((float) bounds.width()) / ((float) mPoints); float cellHeight = ((float) bounds.height()) / ((float) mPoints); float min = Math.min(cellWidth, cellHeight); mSize = min / (mPoints - 1); for (int i = 0; i < mPoints; i++) { // top row posX[i] = bounds.left + cellWidth * (float) i + cellWidth / 2; posY[i] = bounds.top + cellHeight / 2; } for (int i = 0; i < mPoints - 2; i++) { // sides // right side top bottom posX[mPoints + i] = bounds.left + cellWidth * (mPoints - 1) + cellWidth / 2; posY[mPoints + i] = bounds.top + cellHeight * (i + 1) + cellHeight / 2; //left side bottom top posX[3 * mPoints - 2 + i] = bounds.left + cellWidth / 2; posY[3 * mPoints - 2 + i] = bounds.top + cellHeight * (mPoints - 2 - i) + cellHeight / 2; } for (int i = 0; i < mPoints; i++) { // bottom from right to left posX[2 * mPoints - 2 + i] = bounds.left + cellWidth * (mPoints - 1 - i) + cellWidth / 2; posY[2 * mPoints - 2 + i] = bounds.top + cellHeight * (mPoints - 1) + cellHeight / 2; } } @Override public void draw(Canvas canvas) { if (isRunning()) { // animation in progress final int save = canvas.save(); long timeDiff = SystemClock.uptimeMillis() - mStartTime; float progress = ((float) timeDiff) / ((float) mDuration); // 0..1 int level = ((int) (progress * posX.length)) % posX.length; // current value 0..posX.length for (int i = 0; i < posX.length; i++) { if ((i >= level && i < level + mAnimatedPoints) || level + mAnimatedPoints > posX.length && i < (level + mAnimatedPoints) % posX.length) { float num = (i - level + posX.length) % posX.length; // 0..5 float size = mSize * (1 + (num * (1f / mAnimatedPoints))); float sizeNext = mSize * (1 + ((num + 1) * (1f / mAnimatedPoints))); float levelProgress = progress * posX.length - (int) (progress * posX.length); float currentSize; if (num == (mAnimatedPoints - 1)) { // grow to next size currentSize = mSize + (size - mSize) * levelProgress; } else { // shrink currentSize = size + (sizeNext - size) * (1 - levelProgress); } canvas.drawCircle(posX[i], posY[i], currentSize, mPaint); } else { canvas.drawCircle(posX[i], posY[i], mSize, mPaint); } } canvas.restoreToCount(save); } else { // draw normal for (int i = 0; i < posX.length; i++) { canvas.drawCircle(posX[i], posY[i], mSize, mPaint); } } } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); init(); } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter colorFilter) { } @Override public int getOpacity() { return 0; } @Override public void start() { if (mRunning) stop(); mRunning = true; mStartTime = SystemClock.uptimeMillis(); invalidateSelf(); scheduleSelf(this, SystemClock.uptimeMillis() + FRAME_DELAY); } @Override public void stop() { unscheduleSelf(this); mRunning = false; } @Override public boolean isRunning() { return mRunning; } @Override public void run() { invalidateSelf(); long uptimeMillis = SystemClock.uptimeMillis(); if (uptimeMillis + FRAME_DELAY < mStartTime + mDuration) { scheduleSelf(this, uptimeMillis + FRAME_DELAY); } else { mRunning = false; start(); } } public void setAnimatedPoints(int animatedPoints) { mAnimatedPoints = animatedPoints; } } 

Usar con

  ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress); progressBar.setIndeterminateDrawable(new RectProgressDrawable()); progressBar.setIndeterminate(true); 

Alternativamente, puede ver el código fuente completo en un proyecto de trabajo aquí

Lo estoy haciendo con un montón de imágenes y animation-list :

 <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/loadingAnimationImageView" android:layout_width="36dp" android:layout_height="36dp" android:background="@drawable/loading_progress_indicator_animation" /> 

Y res\drawable\loading_progres_indicator_animation.xml :

 <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/selected" android:oneshot="false"> <item android:drawable="@drawable/loading_progress_indicator_0" android:duration="40" /> <item android:drawable="@drawable/loading_progress_indicator_1" android:duration="40" /> <item android:drawable="@drawable/loading_progress_indicator_2" android:duration="40" /> ..... <item android:drawable="@drawable/loading_progress_indicator_11" android:duration="40" /> <item android:drawable="@drawable/loading_progress_indicator_12" android:duration="40" /> </animation-list> 

Donde cada imagen loading_progress_indicator_XX es un indicador de estado de progreso.

La vista personalizada con el indicador:

 public final class LoadingAnimationView extends FrameLayout { ImageView loadingAnimationImageView; AnimationDrawable loadingProgressAnimation; Handler handler = new Handler(Looper.getMainLooper()); public LoadingAnimationView(Context context) { super(context); initialize(); } private void initialize() { LayoutInflater.from(getContext()).inflate(R.layout.view_loading_videoview, this); loadingAnimationImageView = (ImageView)getView().findViewById(R.id.loadingAnimationImageView); loadingProgressAnimation = (AnimationDrawable) loadingAnimationImageView.getBackground(); adaptToVisibility(getVisibility()); } @Override public void setVisibility(int visibility) { super.setVisibility(visibility); adaptToVisibility(visibility); } void adaptToVisibility(final int visibility) { if (visibility == VISIBLE) { loadingProgressAnimation.start(); //This is to avoid "blinking" of progress indicator (if page is loading from cache) handler.postDelayed(new Runnable() { @Override public void run() { loadingAnimationImageView.setVisibility(visibility); } }, 200); } else { loadingProgressAnimation.stop(); loadingAnimationImageView.setVisibility(visibility); } } } 

Como resultado, en mi caso se ve como:

Introduzca aquí la descripción de la imagen

Así que todo lo que necesitará son los estados de su indicador y vista personalizada como la anterior.

Para obtener los estados de su indicador, puede convertir gif a lista de png s Sugeriría utilizar el servicio EzGif :

Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen

Otra opción – usted puede reutilizar uno de docenas de implementaciones personalizadas de indicador de carga como éste (tiene algunos lo suficientemente cerca de sus indicadores) o éste (aunque, la mayoría de los indicadores opensource son circulares).

Espero que ayude.

Sí, necesitas crear una vista personalizada para esto, pero hay una biblioteca adicional de Android que podría ser útil para ti.

Por favor, consulte: https://github.com/mrwonderman/android-square-progressbar

Ejemplos de uso de esta biblioteca:

Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen

Compruebe también esto: ¿Cómo hacer una barra de progreso cuadrada con el cambio de color en cierto intervalo de tiempo?

Aquí encontrará cómo crear su propia implementación de este lib.

Espero que ayude

  • ¿Es posible crear un VectorDrawable desde el sistema de archivos (archivo * .xml)
  • Gradle falla: nodo no soportado 'item' en ids.xml
  • Haga referencia al id de una vista dentro de un diseño "include" en xml
  • Submenú del menú del cajón de navegación
  • Botón de acción flotante de Android Semi Transparente Color de fondo
  • Adaptador de llamada de reconocimiento de voz de Android
  • Defina un atributo necesario para <declare-stylable>
  • ¿Cómo establezco el estado de clic para mi botón personalizado?
  • Cómo definir caracteres especiales en la matriz de implementación de java Aplicación?
  • Las sugerencias de auto de EditText están en blanco o no existen
  • Buscar en archivo XML con XPath en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.