2015-12-30 15 views
20

Voglio creare una barra di avanzamento per Android. Ho quattro immagini per la mia barra di avanzamento a forma di quadrato.Modifica dell'immagine risorsa della barra di avanzamento

Sto usando l'androide barra di avanzamento definito:

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

Ma se voglio fare un quadrato al posto del cerchio come posso farlo? Come posso passare le mie 4 immagini alla barra di avanzamento?

esempio:

enter image description here

+0

@NileshSingh La mia domanda riguarda le immagini, cioè per il colore. –

+0

È necessario avere il proprio approccio. Inserisci il codice che hai scritto in modo che altri possano aiutarti. –

risposta

14

In genere si ha 2 opzioni:

1. Come già accennato, utilizzare un animation-list e sufficiente sostituire le immagini.

Questa è probabilmente la soluzione più semplice, dal momento che possono essere animate relativamente facilmente con AnimationDrawable. L'unico inconveniente sarebbe che hai bisogno di almeno 16 immagini (in tutte le risoluzioni) per il risultato dato.

2. Utilizzare un drawable personalizzato.

Questo è l'approccio più complicato. Dovrai fare il disegno e animare te stesso, che è un compito difficile per la maggior parte delle persone con poca documentazione.

Pertanto è necessario extends Drawable implements Runnable, Animatable e fornire alcune buone implementazioni.

Quello che segue è una stimolazione di base, calcolando le posizioni una volta, quindi disegnandole. L'animazione (la dimensione dei singoli circoli) può e deve essere ulteriormente ottimizzato;)

Risultato in 3 varianti:
Progree Bars

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

Usa con

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

In alternativa si può vedere il codice sorgente completo in un progetto di lavoro here

4

Sì, è necessario creare una visualizzazione personalizzata per questo, ma non v'è una libreria aggiuntiva di Android che potrebbe essere utile per voi.

Si prega di verificare: https://github.com/mrwonderman/android-square-progressbar

esempi di utilizzo di questa libreria:

enter image description here enter image description here enter image description here enter image description here enter image description here

controllare anche questo: How to make a Square progress-bar with changing color in certain time interval?

Qui troverai come creare la tua implementazione di questa lib.

La speranza è aiutare

+0

@J_Strauton, controlla anche questo http://stackoverflow.com/questions/24218153/how-to-make-a-square-progress-bar-with-changing-color-in-certain-time-interval – piotrek1543

9

lo sto facendo con il mazzo di immagini e 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" /> 

E 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> 

Dove ogni immagine loading_progress_indicator_XX è uno stato di indicatore di progresso .

la visualizzazione personalizzata con indicatore:

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

Di conseguenza, nel mio caso sembra che:

enter image description here

Quindi tutto quello che vi serve è gli stati del vostro indicatore & personalizzato vedere come sopra.

Per ottenere stati di vostro indicatore, è possibile convertire gif alla lista dei png s io suggerirei di usare EzGif service:

enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

Un'altra opzione - puoi riutilizzare una delle dozzine di implementazioni personalizzate dell'indicatore di caricamento come this one (ha alcuni abbastanza vicino ai vostri indicatori) o this one (sebbene, la maggior parte degli indicatori di opensource siano circolari).

Spero che aiuti.

Problemi correlati