studio programacion móviles libros libro desarrollo desarrollar curso aprende aplicaciones java android xml android-layout android-progressbar

java - programacion - Modificando la imagen de recursos de la barra de progreso



manual de programacion android pdf (3)

Generalmente tienes 2 opciones :

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

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

2. Usa un dibujo personalizable.

Este es el enfoque más complicado. Tendrá que hacer el dibujo y la animación usted mismo, que es una tarea difícil para la mayoría de las personas con poca buena documentación.

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

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

Resultado en 3 variantes:

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 here

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

Estoy usando la barra de progreso definida de 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:


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 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 parece a:

Por lo tanto, todo lo que necesitará son los estados de su indicador y vista personalizada como la que se muestra arriba.

Para obtener los estados de su indicador, puede convertir gif a la lista de png s que sugiero que usen el servicio EzGif :

Otra opción: puede reutilizar una de las docenas de implementaciones personalizadas del indicador de carga como esta (tiene algunos lo suficientemente cerca de sus indicadores) o esta (aunque, la mayoría de los indicadores de código abierto son circulares).

Espero que ayude.