Lorsque j'utilise des éléments de dessin de la AppCompat
bibliothèque pour mes Toolbar
éléments de menu, la teinte fonctionne comme prévu. Comme ça:
<item
android:id="@+id/action_clear"
android:icon="@drawable/abc_ic_clear_mtrl_alpha" <-- from AppCompat
android:title="@string/clear" />
Mais si j'utilise mes propres dessinables ou même que je copie les dessinables de la AppCompat
bibliothèque dans mon propre projet, cela ne teinte pas du tout.
<item
android:id="@+id/action_clear"
android:icon="@drawable/abc_ic_clear_mtrl_alpha_copy" <-- copy from AppCompat
android:title="@string/clear" />
Y a-t-il une magie spéciale dans le AppCompat
Toolbar
seul dessinable de teinte de cette bibliothèque? Un moyen de faire fonctionner cela avec mes propres drawables?
Exécuter ceci sur un appareil de niveau API 19 avec compileSdkVersion = 21
et targetSdkVersion = 21
, et également utiliser tout ce quiAppCompat
abc_ic_clear_mtrl_alpha_copy
est une copie exacte du abc_ic_clear_mtrl_alpha
png deAppCompat
Éditer:
La teinte est basée sur la valeur que j'ai définie android:textColorPrimary
dans mon thème.
Par exemple, <item name="android:textColorPrimary">#00FF00</item>
me donnerait une teinte verte.
Captures d'écran
La teinture fonctionne comme prévu avec drawable depuis AppCompat
La teinture ne fonctionne pas avec le dessin copié depuis AppCompat
Réponses:
Parce que si vous regardez le code source du TintManager dans AppCompat, vous verrez:
Ce qui signifie à peu près qu'ils ont des resourceIds particuliers sur la liste blanche pour être teintés.
Mais je suppose que vous pouvez toujours voir comment elles teignent ces images et faire de même. C'est aussi simple que de définir le ColorFilter sur un dessin.
la source
Après la nouvelle bibliothèque de support v22.1, vous pouvez utiliser quelque chose de similaire à ceci:
la source
setColorFilter()
est bien préférable.Définir une
ColorFilter
(teinte) sur aMenuItem
est simple. Voici un exemple:Le code ci-dessus est très utile si vous souhaitez prendre en charge différents thèmes et que vous ne souhaitez pas avoir de copies supplémentaires uniquement pour la couleur ou la transparence.
Cliquez ici pour une classe d'assistance pour définir un
ColorFilter
sur tous les dessinables dans un menu, y compris l'icône de débordement.En
onCreateOptionsMenu(Menu menu)
appelez justeMenuColorizer.colorMenu(this, menu, color);
après avoir gonflé votre menu et le tour est joué; vos icônes sont teintées.la source
app:iconTint
L'attribut est implémenté dans àSupportMenuInflater
partir de la bibliothèque de support (au moins dans 28.0.0).Testé avec succès avec l'API 15 et plus.
Fichier de ressources de menu:
(Dans ce cas, il y
?attr/appIconColorEnabled
avait un attribut de couleur personnalisé dans les thèmes de l'application et les ressources d'icônes étaient des dessins vectoriels.)la source
android:iconTint
etandroid:iconTintMode
ne fonctionne pas, mais préfixer avecapp:
au lieu deandroid:
fonctionne comme un charme (sur mes propres dessins vectoriels, API> = 21)SupportMenuInflater
cela n'appliquera aucune logique personnalisée si le menu n'est pasSupportMenu
similaireMenuBuilder
, il revient simplement à normalMenuInflater
.AppCompatActivity.startSupportActionMode(callback)
et les implémentations de support appropriées deandroidx.appcompat
seront passées dans le rappel.J'ai personnellement préféré cette approche à partir de ce lien
Créez une mise en page XML avec les éléments suivants:
et référencez ce dessinable à partir de votre menu:
la source
bitmap
. Il existe d'autres façons de colorer les vecteurs. Peut-être que quelqu'un pourrait ajouter une coloration vectorielle ici aussi ...La plupart des solutions de ce thread utilisent une API plus récente, ou utilisent la réflexion, ou utilisent une recherche de vue intensive pour obtenir le gonflé
MenuItem
.Cependant, il existe une approche plus élégante pour le faire. Vous avez besoin d'une barre d'outils personnalisée, car votre cas d'utilisation «appliquer une teinte personnalisée» ne fonctionne pas bien avec l'API de style / thématisation publique.
Assurez-vous simplement d'appeler votre code d'activité / fragment:
Pas de réflexion, pas de recherche de vue, et pas tellement de code, hein?
Et maintenant, vous pouvez ignorer le ridicule
onCreateOptionsMenu/onOptionsItemSelected
.la source
Menu#getItem()
complexité est O (1) dans la barre d'outils, car les éléments sont stockés dans ArrayList. Ce qui est différent de laView#findViewById
traversée (que j'ai appelée recherche de vue dans ma réponse), dont la complexité est loin d'être constante :-)Voici la solution que j'utilise; vous pouvez l'appeler après onPrepareOptionsMenu () ou le lieu équivalent. La raison de mutate () est si vous utilisez les icônes à plusieurs endroits; sans le mutate, ils prendront tous la même teinte.
Cela ne prendra pas en charge le débordement, mais pour cela, vous pouvez le faire:
Disposition:
Modes:
Cela fonctionne depuis appcompat v23.1.0.
la source