53 votes

Comment créer une barre de progression personnalisée en forme de cercle dans Android

Je veux personnaliser la barre de progression en forme de cercle comme dans l'exemple suivant télécharger le blazer Je suis attendu comme la capture d'écran ci-dessous :

enter image description here

Quelqu'un peut-il m'aider à faire cela ?

2 votes

1 votes

J'ai trouvé cet exemple très bon. mrigaen.blogspot.it/2013/12/

0 votes

Peut-être que ceci peut vous orienter dans la bonne direction github.com/grmaciel/two-level-circular-progress-bar

34voto

promachos4 Points 166

Les deux meilleures bibliothèques que j'ai trouvées sur le net sont sur Github. https://github.com/Todd-Davies/ProgressWheel https://github.com/f2prateek/progressbutton?source=c J'espère que cela vous aidera

0 votes

C'est exactement ce que je recherchais. Merci

0 votes

La première est exactement celle qu'utilise l'application Play Music de Google. C'est grandiose !

0 votes

Vous pouvez aussi essayer celui-ci, très simple à utiliser : github.com/daentech/CircularDemo

32voto

Alex Points 79

J'ai rencontré le même problème et je n'ai pas trouvé de solution appropriée à mon cas, j'ai donc décidé de suivre une autre voie. J'ai créé une classe drawable personnalisée. Dans cette classe, j'ai créé 2 peintures pour la ligne de progression et la ligne de fond (avec un trait plus grand). Tout d'abord, il faut définir startAngle et sweepAngle dans le constructeur :

    mSweepAngle = 0;
    mStartAngle = 270;

Voici la méthode onDraw de cette classe :

@Override
public void draw(Canvas canvas) {
    // draw background line
    canvas.drawArc(mRectF, 0, 360, false, mPaintBackground);
    // draw progress line
    canvas.drawArc(mRectF, mStartAngle, mSweepAngle, false, mPaintProgress);
}

Maintenant, tout ce que vous avez à faire, c'est de définir ce dessinable comme un arrière-plan de la vue, et de modifier sweepAngle dans le fil d'arrière-plan :

mSweepAngle += 360 / totalTimerTime // this is mStep

et appelez directement InvalidateSelf() avec un certain intervalle (par exemple toutes les 1 secondes ou plus souvent si vous voulez des changements de progression fluides) sur la vue qui a ce drawable comme arrière-plan. C'est tout !

P.S. Je sais, je sais... bien sûr vous voulez un peu plus de code. Alors le voici, tout en fluidité :

  1. Créer une vue XML :

     <View
     android:id="@+id/timer"
     android:layout_width="match_parent"
     android:layout_height="match_parent"/>
  2. Créez et configurez la classe Custom Drawable (comme je l'ai décrit ci-dessus). N'oubliez pas de configurer les peintures pour les lignes. Ici la peinture pour la ligne de progression :

    mPaintProgress = new Paint();
    mPaintProgress.setAntiAlias(true);
    mPaintProgress.setStyle(Paint.Style.STROKE);
    mPaintProgress.setStrokeWidth(widthProgress);
    mPaintProgress.setStrokeCap(Paint.Cap.ROUND);
    mPaintProgress.setColor(colorThatYouWant);

Même chose pour la peinture d'arrière-plan (réglez la largeur un peu plus si vous voulez).

  1. Dans la classe drawable, créer une méthode de mise à jour (étape de calcul décrite ci-dessus).

    public void update() {
        mSweepAngle += mStep;
        invalidateSelf();
    }
  2. Définissez cette classe de dessinateur à YourTimerView (je l'ai fait dans le runtime) - vue avec @+id/timer du xml ci-dessus :

    OurSuperDrawableClass superDrawable = new OurSuperDrawableClass(); YourTimerView.setBackgroundDrawable(superDrawable);

  3. Créez un thread d'arrière-plan avec un runnable et une vue de mise à jour :

    YourTimerView.post(new Runnable() {
        @Override
        public void run() {
            // update progress view
            superDrawable.update();
        }
    });

C'est ça ! Profitez de votre barre de progression. Voici une capture d'écran du résultat si vous êtes trop ennuyé par cette quantité de texte. enter image description here

0 votes

J'utilise actuellement une boucle while dans un UIthread dans le poste. Cependant, il ne se met à jour que lorsqu'il est entièrement terminé. Quelqu'un sait-il ce qui ne va pas ?

0 votes

@JordiSipkens vous ne pouvez pas utiliser la boucle while dans UIThread car vous bloquez l'interface utilisateur, effectuez les opérations en arrière-plan et mettez à jour la vue aussi souvent que vous le souhaitez. Si vous mettez à jour la vue toutes les millisecondes, l'animation sera plus fluide. Vous pouvez faire en sorte que mProgress++ soit exécuté en arrière-plan avec Thread.sleep(1) et mettre à jour la vue avec mView.post() ;

0 votes

En utilisant cette approche, comment puis-je changer dynamiquement la couleur de la barre de progression circulaire après certains intervalles ? disons par exemple 0-50 couleur rouge, 51-100 couleur bleue ? et l'animation entière devrait être dans une animation lisse ?

6voto

Faakhir Points 346

Un outil très utile lib pour une barre de progression personnalisée dans Android.

Dans votre fichier de mise en page

<com.lylc.widget.circularprogressbar.example.CircularProgressBar
android:id="@+id/mycustom_progressbar"
.
.
.
 />

et le fichier Java

CircularProgressBar progressBar = (CircularProgressBar) findViewById(R.id.mycustom_progressbar);
progressBar.setTitle("Circular Progress Bar");

6voto

mani345 Points 170

Essayez ce morceau de code pour créer une barre de progression circulaire (camembert). Passez-lui une valeur entière pour dessiner combien de pourcent de la zone remplie. :)

private void circularImageBar(ImageView iv2, int i) {

    Bitmap b = Bitmap.createBitmap(300, 300,Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(b); 
    Paint paint = new Paint();

        paint.setColor(Color.parseColor("#c4c4c4"));
        paint.setStrokeWidth(10);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(150, 150, 140, paint);
        paint.setColor(Color.parseColor("#FFDB4C"));
        paint.setStrokeWidth(10);   
        paint.setStyle(Paint.Style.FILL);
        final RectF oval = new RectF();
        paint.setStyle(Paint.Style.STROKE);
        oval.set(10,10,290,290);
        canvas.drawArc(oval, 270, ((i*360)/100), false, paint);
        paint.setStrokeWidth(0);    
        paint.setTextAlign(Align.CENTER);
        paint.setColor(Color.parseColor("#8E8E93")); 
        paint.setTextSize(140);
        canvas.drawText(""+i, 150, 150+(paint.getTextSize()/3), paint); 
        iv2.setImageBitmap(b);
}

0voto

Gabe Sechan Points 23732

Je créerais une nouvelle classe de vue et je dériverais de la ProgressBar existante. Ensuite, il faut surcharger la fonction onDraw. Vous allez avoir besoin de faire des appels directs au canvas pour cela, puisque c'est tellement personnalisé - une combinaison de drawText, drawArc, et drawOval devrait le faire - un ovale pour l'anneau extérieur et les parties vides, et un arc pour les parties colorées. Vous aurez peut-être besoin de remplacer onMeasure et onLayout également. Ensuite, dans votre xml, référencez cette vue par le nom de la classe comme ceci lorsque vous voulez l'utiliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X