webentwicklung-frage-antwort-db.com.de

Glatte Fortschrittsbalkenanimation

Ich versuche eine glatte Animation für meine ProgressBar zu implementieren, aber wenn ich die Zeit verlängere (30 Sekunden), ist die Animation nicht mehr glatt.

Beispiel mit 5 Sekunden: 

5 seconds

Beispiel mit 30 Sekunden:

30 seconds

Mein Fortschrittshintergrund:

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item>
        <shape>
            <padding Android:top="1dp" />
            <solid Android:color="#10444444" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" />
            <solid Android:color="#20444444" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" />
            <solid Android:color="#30444444" />
        </shape>
    </item>
    <item Android:id="@Android:id/background">
        <shape>
            <solid Android:color="@color/black_thirty" />
        </shape>
    </item>

    <item Android:id="@Android:id/progress">
        <clip>
            <shape>
                <solid Android:color="#3500D0" />
            </shape>
        </clip>
    </item>
</layer-list> 

Mein Fortschrittslayout:

<ProgressBar
    Android:id="@+id/pb_loading"
    Android:layout_width="match_parent"
    Android:layout_height="8dp"
    Android:indeterminate="false"
    Android:layout_centerInParent="true"
    Android:progress="100"
    Android:progressDrawable="@drawable/my_progress_bar" />

Meine Animationsmethode:

private void startAnimation(){
    ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.pb_loading);
    ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 100, 0);
    progressAnimator.setDuration(30000);
    progressAnimator.setInterpolator(new LinearInterpolator());
    progressAnimator.start();
}
19
rsicarelli

Da Sie ofInt verwenden, können Sie sich nur mit ganzen Zahlen bewegen. Mit anderen Worten, wenn Sie einen Fortschrittsbalken mit einer Breite von 1000 und einem Fortschritt von 0 bis 100 haben, da Sie sich in einem ganzzahligen Tempo bewegen, zählen Sie 1, 2, 3, 4, was zu 10px, 20px, 30px und 40px führt. Was erklärt die Schräge, die Sie sehen. 

Um dies zu korrigieren, haben Sie einige Möglichkeiten. Die erste besteht darin, Ihre Ganzzahlen von 0 auf someBigInt zu erhöhen. Dadurch erhält der Animator mehr Zahlen, mit denen er arbeiten kann.

ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 10000, 0);

Die andere Option ist die Verwendung von ofFloat, die dasselbe tut wie ofInt, jedoch Gleitpunkte anstelle von Ganzzahlen verwendet.

ObjectAnimator progressAnimator = ObjectAnimator.ofFloat(mProgressBar, "progress", 100.0, 0.0);
23
Chris Stillwell

Wenn Sie den Fortschrittswert jedes Mal um 1 ändern (z. B. von 45 auf 46), wird die Animation nicht angezeigt. Sie sollten den Fortschritt besser um 100 Punkte (oder vielleicht andere) ändern. Dazu müssen Sie lediglich Ihren Maximalwert mit 100 und jeden Fortschrittswert ebenfalls mit 100 multiplizieren. Zum Beispiel:

    private void setProgressMax(ProgressBar pb, int max) {
        pb.setMax(max * 100);
    }

    private void setProgressAnimate(ProgressBar pb, int progressTo) 
    {
        ObjectAnimator animation = ObjectAnimator.ofInt(pb, "progress", pb.getProgress(), progressTo * 100);
        animation.setDuration(500);
        animation.setInterpolator(new DecelerateInterpolator());
        animation.start();
    }
16
Pavel Kataykin

Setze einfach Android:max="1000" Und mache ObjectAnimator progressAnimator = ObjectAnimator.ofInt(mProgressBar, "progress", 1000, 0);

in diesem Fall animieren Sie 1/1000 bei jedem Schritt, der in 10-mal reibungslos abläuft, wenn standardmäßig 100 Prozent skaliert sind. und es sieht viel besser aus

6
Hawkins

XML

       <ProgressBar
        Android:id="@+id/progress_bar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        Android:layout_width="match_parent"
        Android:layout_height="4dp"
        Android:indeterminate="false"
        Android:progress="0"
        Android:max="100"/>

Java

@BindView(R.id.progress_bar) ProgressBar progressBar;
ObjectAnimator.ofInt(progressBar, "progress", 79).start();

79

  • eine beliebige Zahl zwischen 0 und 100 für dieses Beispiel
3
Shwarz Andrei

Sie können nicht die ofFloat verwenden, da das progress-Attribut der ProgressBar keine Float-Werte akzeptiert, sondern nur ganzzahlige Werte. Aus diesem Grund hat Ihre ProgressBar nach dieser Lösung keinen Fortschritt mehr gemacht.

Wie die anderen gesagt haben, ist der richtige Weg, um das zu tun, was Sie wollen, Android:max auf eine große Ganzzahl zu setzen.

Es tut mir leid für die Wiederbelebung des Threads, aber ich denke, das musste gesagt werden.

2
zivko

Wenn Sie Android N und höher haben, können Sie verwenden:

progressBar.setProgress(newProgress, true)

Dokumente:

Legt den aktuellen Fortschritt auf den angegebenen Wert fest und animiert optional die visuelle Position zwischen dem aktuellen Wert und dem Zielwert.

Die Animation hat keinen Einfluss auf das Ergebnis von getProgress (), das den Zielwert unmittelbar nach dem Aufruf dieser Methode zurückgibt.

https://developer.Android.com/reference/Android/widget/ProgressBar.html#setProgress (int,% 20boolean)

2

Wenn Sie die Bibliothek verwenden, geben Sie der Zeit, in der Sie den Fortschrittsbalken füllen möchten, eine sehr reibungslose Zeit ohne Verzögerung, aber Sie können diese Funktion ein wenig anpassen.

Fügen Sie die Abhängigkeit einfach zu Ihrem build.gradle hinzu:

compile 'com.carlosmuvi.segmentedprogressbar:library:0.2'

Als nächstes fügen Sie es Ihrem Layout hinzu

  <com.carlosmuvi.segmentedprogressbar.SegmentedProgressBar
      Android:id="@+id/segmented_progressbar"
      Android:layout_width="match_parent"
      Android:layout_height="5dp"/>

Passen Sie es schließlich programmatisch an und spielen Sie es!

segmentedProgressBar = (SegmentedProgressBar) findViewById(R.id.segmented_progressbar);

// number of segments in your bar
segmentedProgressBar.setSegmentCount(7); 

//empty segment color
segmentedProgressBar.setContainerColor(Color.BLUE); 
//fill segment color
segmentedProgressBar.setFillColor(Color.GREEN); 

//play next segment specifying its duration
segmentedProgressBar.playSegment(5000);

//pause segment
segmentedProgressBar.pause();

//set filled segments directly
segmentedProgressBar.setCompletedSegments(3);

Geh zur Bibliothek

0
Arslan Maqbool

hier ist ein Ausschnitt für meinen Countdown-Timer. Die Animation kann je nach Bedarf angepasst werden.

private void setProgressBarValues() {
        progressBarCircle.setMax((int) (timeCountInMilliSeconds / 10));
        progressBarCircle.setProgress((int) (timeCountInMilliSeconds / 10));
        Log.e("progres", "" + (timeCountInMilliSeconds / 10));
    }

private void startCountDownTimer() {

        smoothAnimation = ObjectAnimator.ofInt(progressBarCircle, "progress", progressBarCircle.getProgress(), progressBarCircle.getMax());
        smoothAnimation.setDuration(500);
        smoothAnimation.setInterpolator(new AccelerateInterpolator());

        countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 10) {
            @Override
            public void onTick(long millisUntilFinished) {

                Log.e("getMax", "" + progressBarCircle.getMax());
                Log.e("getprogres", "" + progressBarCircle.getProgress());
                textViewTime.setText(hmsTimeFormatter(millisUntilFinished));
                progressBarCircle.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
            }

            @Override
            public void onFinish() {

                textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
                // call to initialize the progress bar values
                setProgressBarValues();
                // hiding the reset icon
                buttonReset.setEnabled(false);
                // making edit text editable
                editTextMinute.setEnabled(true);
                // changing the timer status to stopped
                status = TimerStatus.STOPPED;
                smoothAnimation.end();
            }

        }.start();
        smoothAnimation.start();
        countDownTimer.start();
    }

Zusammenfassung:

  1. setMax und setProgress

  2. setAnimation, um vom Fortschritt bis zu den maximalen Fortschrittsbalken anzuzeigen 

  3. erstellen Sie einen Timer mit einem Rückruf von ~ 10 Millisekunden 

  4. update-Fortschritt in onTick, also insgesamt - abgeschlossen

0
Chetan Garg

Sie können benutzerdefinierte Klassen wie folgt erstellen:

public class CustomProgressBar extends ProgressBar {
private static final long DEFAULT_DELAY = 500;
private static final long DEFAULT_DURATION = 1000;

public CustomProgressBar(Context context) {
    super(context);
}

public CustomProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public synchronized void setProgress(float progress) {
    super.setProgress((int) progress);
}

@Override
public synchronized void setProgress(int progress) {
    super.setProgress(progress);
}

public void startLcpProgressAnim(int progressTo) {
   startLcpProgressAnim(DEFAULT_DELAY, progressTo);
}

public void startLcpProgressAnim(long delay, int progressTo) {
   startLcpProgressAnim(DEFAULT_DURATION, delay, progressTo);
}

public void startLcpProgressAnim(long duration, long delay, float progressTo) {
    ObjectAnimator animation = ObjectAnimator.
            ofFloat(this, "progress",
                    (float)this.getProgress(), progressTo);
    animation.setDuration(duration);
    animation.setStartDelay(delay);
    animation.start();
}
}
0
manmohan