2015-12-30 7 views
20

Ich möchte eine Fortschrittsanzeige für Android erstellen. Ich habe vier Bilder für meinen quadratischen Fortschrittsbalken.Ändern der Ressource Bild von Progress Bar

ich die android definiert Fortschrittsbalken bin mit:

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

Aber wenn ich will ein Quadrat anstelle des Kreises machen, wie kann ich es tun? Wie gebe ich meine 4 Bilder an den Fortschrittsbalken weiter?

Beispiel:

enter image description here

+0

@NileshSingh Meine Frage bezieht sich auf Bilder, also auf Farbe. –

+0

Sie müssen Ihren eigenen Ansatz haben. Schreiben Sie etwas Code, den Sie geschrieben haben, damit andere helfen können. –

Antwort

14

Im Allgemeinen haben Sie 2 Möglichkeiten haben:

1. Wie bereits erwähnt, verwenden ein animation-list und nur Bilder tauschen.

Dies ist wahrscheinlich die einfachere Lösung, da sie relativ einfach mit AnimationDrawable animiert werden können. Der einzige Nachteil wäre, dass Sie für Ihr Ergebnis mindestens 16 Bilder (in allen Auflösungen) benötigen.

2. Verwenden Sie einen benutzerdefinierten Zeichensatz.

Dies ist der kompliziertere Ansatz. Sie müssen selbst zeichnen und animieren, was für die meisten Menschen mit wenig guter Dokumentation eine schwierige Aufgabe ist.

Daher müssen Sie extends Drawable implements Runnable, Animatable und einige gute Implementierungen liefern.

Das folgende ist eine grundlegende Implementierung, die Positionen einmal berechnet, dann zeichnend. Die Animation (die Größe der einzelnen Kreise) und weiter optimiert werden soll;)

Ergebnis in 3 Varianten:
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; 
    } 
} 

Verwendung mit

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

Sie Alternativ kann den vollen Quellcode in einem Arbeitsprojekt sehen here

4

Ja, Sie müssen eine benutzerdefinierte Ansicht für diese schaffen, aber es gibt eine zusätzliche Android-Bibliothek, die für Sie nützlich sein könnten.

Bitte überprüfen Sie: https://github.com/mrwonderman/android-square-progressbar

Beispiele für die Verwendung dieser Bibliothek:

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

prüfen auch dies: How to make a Square progress-bar with changing color in certain time interval?

Hier finden Sie, wie Sie eine eigene Implementierung dieser Bibliothek erstellen können.

Hoffe, dass es

+0

@J_Strauton, überprüfen Sie auch diese http://stackoverflow.com/questions/24218153/how-to-make-a-square-progress-bar-with-changing-color-in-certain-time-interval – piotrek1543

9

helfen ich tue es mit Haufen von Bildern und 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" /> 

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

Wo jedes loading_progress_indicator_XX Bild ein Zustand des Fortschrittsanzeige ist .

Die benutzerdefinierte Ansicht mit Anzeige:

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

Als Ergebnis sieht in meinem Fall ist es wie:

enter image description here

Also alles, was Sie benötigen, um die Zustände Ihrer Anzeige & Brauch sehe wie oben.

Um Zustände Ihrer Anzeige erhalten Sie gif zur Liste png s konvertieren können ich EzGif service verwenden würde vorschlagen:

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

Eine weitere Option - Sie können eine von Dutzenden benutzerdefinierten Implementierungen des Lade-Indikators wie this one (es hat einige nahe genug zu Ihren Indikatoren) oder this one (obwohl die meisten Opensource-Indikatoren zirkulär sind).

Ich hoffe es hilft.