web-dev-qa-db-fra.com

Android - Tinting ProgressBar sur les appareils pré-Lollipop

Le niveau d'API minimal de mon application est de 19 (KitKat) et contient une disposition avec un ProgressBar horizontal. J'utilise Android:progressTint attribut pour teinter la barre en une couleur personnalisée. Cela fonctionne assez bien sur Lollipop (API 21) et au-dessus, mais en dessous (par exemple sur l'API 19), il ne fonctionne pas; il apparaît dans une couleur différente. La raison en est que cet attribut

est uniquement utilisé dans l'API niveau 21 et supérieur

comme Android États de Studio.

Je me demande donc quelle peut être une bonne alternative pour teinter le ProgressBar sur les appareils pré-Lollipop. Peut-il être fait à l'intérieur du fichier de mise en page avec XML? Ou cela devrait-il être fait d'une manière différente?


EDIT # 1: Mon ProgressBar est utilisé pour afficher des valeurs concrètes en pourcentage, pas pour indiquer que ma mise en page est en cours de chargement. Je tiens à ce que cela soit clair car après avoir essayé ce que Kuldeep Kulkarni a écrit ci-dessous, ma barre ressemblait à un indicateur de chargement de matériau (bien sûr sur l'appareil Lollipop, aucun résultat visible sur l'appareil KitKat).

12
Geryson

Merci pour les suggestions de tout le monde! :)

La solution qui fonctionne pour moi est de créer un fichier XML dessinable personnalisé avec le <layer-list> élément racine. Là, je définis deux éléments de calque avec les identifiants natifs Android _ @Android:id/background et @Android:id/progress. Après cela, je peux définir les formes et les ressources de couleur que j'aimerais utiliser. Cette solution est similaire à une réponse plus populaire sur this SO question.


Contenu de mon res/drawable/progressbar.xml fichier:

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:id="@Android:id/background">

        <shape>

            <corners Android:radius="2dip" /> <!--optional-->

            <gradient
                Android:angle="270"
                Android:endColor="@color/gray"
                Android:startColor="@color/gray" />

        </shape>

    </item>

    <item Android:id="@Android:id/progress">

        <clip>

            <shape>

                <corners Android:radius="2dip" /> <!--optional-->

                <gradient
                    Android:angle="270"
                    Android:endColor="@color/blue"
                    Android:startColor="@color/blue" />

            </shape>

        </clip>

    </item>

</layer-list>

Défini comme progressDrawable pour mon ProgressBar dans le fichier XML de mise en page:

<ProgressBar
        Android:id="@+id/progress_bar"
        Android:layout_width="0dp"
        Android:layout_height="@dimen/progress_bar_height"
        Android:progressDrawable="@drawable/progressbar" />

Je n'ai pas eu l'occasion de le tester en dessous de l'API 19, mais à ce niveau et au-dessus, cela fonctionne parfaitement.

5
Geryson

Vous pouvez envelopper avec ProgressBar indeterminateDrawable méthode pour pre-Lollipop.

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {

     Drawable drawableProgress = DrawableCompat.wrap(progressBar.getIndeterminateDrawable());
     DrawableCompat.setTint(drawableProgress, ContextCompat.getColor(getContext(), Android.R.color.holo_green_light));
     progressBar.setIndeterminateDrawable(DrawableCompat.unwrap(drawableProgress));

} else {
    progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), Android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN);
}
24
Satan Pandeya
progress.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
10
Elias Nawfal

Ça marche pour moi

<ProgressBar
   Android:layout_width="wrap_content"
   Android:layout_height="wrap_content"
   Android:theme="@style/progressBarBlue" />

Ensuite, dans votre style.xml définir progressBarBlue

<style name="progressBarWhite" parent="@style/Theme.AppCompat">
   <item name="colorAccent">@color/blue</item>
</style>
1
Dennis Mwagiru

Si vous voulez le faire par programme, essayez ceci

public static void setSeekbarTint(SeekBar seekbar, int color) {
        PorterDuff.Mode porterDuffMode = PorterDuff.Mode.SRC_IN;
        if (seekbar.getIndeterminateDrawable() != null)
            seekbar.getIndeterminateDrawable().setColorFilter(color, porterDuffMode);

        if (seekbar.getProgressDrawable() != null &&
                seekbar.getProgressDrawable() instanceof LayerDrawable) {
            LayerDrawable layerDrawable = (LayerDrawable) seekbar.getProgressDrawable();
            GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(Android.R.id.background);

            layerDrawable.setColorFilter(color, porterDuffMode);
            seekbar.setProgressDrawable(layerDrawable);
            gradientDrawable.setColorFilter(Color.WHITE, porterDuffMode);
        } else if (seekbar.getProgressDrawable() != null &&
                seekbar.getProgressDrawable() instanceof ClipDrawable) {
            ClipDrawable clipDrawable = (ClipDrawable) seekbar.getProgressDrawable();
            clipDrawable.setColorFilter(color, porterDuffMode);
            seekbar.setProgressDrawable(clipDrawable);
        }
}
0
Jahnavi Nandamuri