web-dev-qa-db-fra.com

Animation de barre de progression lisse

J'essaie d'implémenter une animation fluide pour ma ProgressBar, mais lorsque j'augmente le temps (30 secondes), l'animation n'est plus fluide.

Exemple avec 5 secondes: 

5 seconds

Exemple avec 30 secondes:

30 seconds

Mon parcours de progrès:

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

Ma mise en page de progression:

<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" />

Ma méthode d'animation:

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

Comme vous utilisez ofInt, vous ne pouvez vous déplacer que sur des entiers entiers. En d’autres termes, si vous avez une barre de progression d’une largeur de 1000 et une progression de 0 à 100 puisque vous vous déplacez à un rythme entier, vous comptez 1, 2, 3, 4, ce qui correspond à 10px, 20px, 30px et 40px. Ce qui explique les irrégularités que vous voyez. 

Pour corriger cela, vous avez quelques options. La première consiste à augmenter vos entiers de 0 à someBigInt Cela donnera à l'animateur plus de nombres avec lesquels travailler.

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

L'autre option consiste à utiliser ofFloat qui fait la même chose que ofInt mais utilise des points flottants au lieu d'entiers.

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

Si vous modifiez chaque fois la valeur de progression de 1 (par exemple de 45 à 46), l'animation ne sera pas affichée. Vous feriez mieux de modifier la progression de 100 points (ou peut-être une autre), il vous suffit pour cela de multiplier votre valeur maximale par 100 et chaque valeur de progression par 100 également. Par exemple:

    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

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

  • un nombre quelconque compris entre 0 et 100 pour cet exemple
3
Shwarz Andrei

Vous pouvez not utiliser la ofFloat car l'attribut progress de ProgressBar n'accepte pas les valeurs flottantes, mais uniquement les entières. C'est pourquoi votre ProgressBar a cessé de progresser après avoir utilisé cette solution.

Comme d'autres l'ont dit, la bonne façon de faire ce que vous voulez est de définir Android:max sur un grand nombre entier.

Désolé de faire revivre le fil, mais je pense que cela devait être dit.

2
zivko

Utilisez la bibliothèque pour vous aider à donner au temps dans lequel vous voulez remplir la barre de progression très lisse sans décalage.

Ajoutez simplement la dépendance à votre build.gradle:

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

Ensuite, ajoutez-le à votre mise en page

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

Enfin, personnalisez-le par programme et jouez-le!

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

Aller à la librairie

0
Arslan Maqbool

voici un extrait de mon compte à rebours utilisant une animation fluide que vous pouvez modifier selon vos besoins, veuillez suivre les étapes suivantes:

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

Résumé:

  1. setMax et setProgress

  2. setAnimation pour montrer du progrès aux valeurs maximales de progressbar 

  3. créer une minuterie avec un rappel d'environ 10 millisecondes 

  4. mise à jour de la progression dans onTick i.e total - terminé

0
Chetan Garg

Vous pouvez créer une classe personnalisée comme ceci:

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