Je suis en train de faire une fonction cadre général qui fait tout Drawable est mis en surbrillance lorsque pressé / concentré / sélectionné / etc .
Ma fonction prend un Drawable et retourne un StateListDrawable, où l'état par défaut est le Drawable lui-même, et l'état pour android.R.attr.state_pressed
est le même drawable, juste avec un filtre appliqué à l'aide de setColorFilter
.
Mon problème est que je ne peux pas cloner le dessinable et en créer une instance séparée avec le filtre appliqué. Voici ce que j'essaye de réaliser:
StateListDrawable makeHighlightable(Drawable drawable)
{
StateListDrawable res = new StateListDrawable();
Drawable clone = drawable.clone(); // how do I do this??
clone.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
res.addState(new int[] {android.R.attr.state_pressed}, clone);
res.addState(new int[] { }, drawable);
return res;
}
Si je ne clone pas, le filtre est évidemment appliqué aux deux états. J'ai essayé de jouer avec mutate()
mais ça n'aide pas.
Des idées?
Mettre à jour:
La réponse acceptée clone en effet un dessinable. Cela ne m'a pas aidé car ma fonction générale échoue sur un problème différent. Il semble que lorsque vous ajoutez un dessinable à une StateList, il perd tous ses filtres.
la source
ImageView.setImageDrawable
, que j'ai pu contourner grâce à la réponse acceptée.Réponses:
Essayez ce qui suit:
la source
.mutate()
(voir ma réponse).Si vous appliquez un filtre / etc à un dessinable créé avec
getConstantState().newDrawable()
alors toutes les instances de ce dessinable seront également modifiées, puisque les dessinables utilisent leconstantState
comme cache!Donc, si vous colorez un cercle en utilisant un filtre de couleur et un
newDrawable()
, vous changerez la couleur de tous les cercles.Si vous souhaitez que ce dessin puisse être mis à jour sans affecter les autres instances, vous devez alors faire muter cet état constant existant.
Pour une bonne explication, voir:
http://www.curious-creature.org/2009/05/02/drawable-mutations/
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate ()
la source
C'est ce qui fonctionne pour moi.
la source
C'est ma solution, basée sur cette question SO .
L'idée est d'
ImageView
obtenir un filtre de couleur lorsque l'utilisateur le touche, et le filtre de couleur est supprimé lorsque l'utilisateur cesse de le toucher. Un seul dessinable / bitmap est en mémoire, donc pas besoin de le gaspiller. Cela fonctionne comme il se doit.usage:
la source
J'ai répondu à une question connexe ici
Fondamentalement, il semble que StateListDrawables perd effectivement ses filtres. J'ai créé un nouveau BitmapDrawale à partir d'une copie modifiée du Bitmap que je voulais utiliser à l'origine.
la source
en cas de
getConstantState()
retournull
.la source
Obtenez le clonage en utilisant
newDrawable()
mais assurez-vous qu'il est mutable sinon votre effet de clone a disparu, j'ai utilisé ces quelques lignes de code et cela fonctionne comme prévu.getConstantState()
peut être nul comme suggéré par l'annotation, alors gérez cette RunTimeException pendant que vous clonez un dessinable.la source