web-dev-qa-db-fra.com

Comment changer la teinte d'un ImageButton sur focus/presse

J'ai une ImageButton dans mon application et je dois changer la teinte de l'image lorsque le bouton est pressed/focused. J'ai la variable ImageButton pour obtenir sa src à partir d'un fichier XML qui se présente comme suit:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <!-- pressed -->
    <item 
        Android:state_pressed="true"
        Android:tint="@color/black"
        Android:drawable="@drawable/search"
        />

    <!-- focused -->
    <item 
        Android:state_focused="true"
        Android:tint="@color/black"
        Android:drawable="@drawable/search"
        />

    <!-- default -->
    <item
        Android:tint="@null"
        Android:drawable="@drawable/search"
        />

</selector>

Toutefois, la teinte n'est pas appliquée lorsque vous appuyez sur la touche ImageButton. L'image s'affiche simplement comme d'habitude. La couleur noire est définie comme #000000 comme toujours. Des idées?

53
Joseph Earl

Vous pouvez changer la teinte, assez facilement dans le code via:

ImageButton button = (ImageButton) this.findViewById(R.id.button_i_want_to_modify);
button.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

J'espère que ça aide.

JS

81
Jeff

Voici comment le faire en utilisant uniquement xml . Dans votre dossier pouvant être dessiné, créez un sélecteur. Par exemple: touch_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
    <item Android:state_pressed="true" Android:color="@color/semi_slate" />

    <!-- When the view is "activated".  In SINGLE_CHOICE_MODE, it flags the active row
     of a ListView -->
    <item Android:state_activated="true" Android:color="@color/semi_slate" />

    <!-- Default, "just hangin' out" state. -->
    <item Android:color="@Android:color/transparent" />
</selector>

Dans ma vue Image en xml, je règle l'attribut Android: tint sur le dessin que l'on a créé ci-dessus. 

Android:tint = "@drawable/touch_selector"

Le code entier ressemblait à ceci:

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/poster"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:adjustViewBounds="true"
Android:scaleType="centerCrop"
Android:tint="@drawable/touch_selector" />

Il s’agit d’une solution 100% XML, permettant de colorer un ImageView sur une presse ou un composant actif . Il est possible de procéder de la même manière pour ImageButton.

Notez que cela ne fonctionne que pour le niveau API> = 21. 

7
Rashi Karanpuria

J'ai trouvé un moyen de le faire en XML (dans api 21 et au moins).

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_pressed="true" >
        <bitmap
            Android:src="@drawable/search"
            Android:tint="@color/black"
            />
    </item>
    <item Android:drawable="@drawable/search"/>
</selector>

En définissant la teinte sur le bitmap, il est possible de réutiliser le même dessin en XML sans avoir à intercepter les touches ou la sous-classe ImageView ou ImageButton.

Une fois le sélecteur créé, appliquez-le simplement en tant que src de ImageView ou ImageButton.

6
ckern

Enfin, j'ai trouvé une solution pour API <21:

Button more = (Button) findViewById(R.id.more);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
    more.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
} else {
    Drawable wrapDrawable = DrawableCompat.wrap(more.getBackground());
    DrawableCompat.setTint(wrapDrawable, color));
    more.setBackgroundDrawable(DrawableCompat.unwrap(wrapDrawable));
}

Puisse ceci aider quelqu'un à ne pas perdre 2 heures!

6
Henrique de Sousa
bt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        bt.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        bt.clearColorFilter(); // White Tint
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });
2
Fu-Lung Chen

J'ai remarqué qu'il y a quelques demandes ici pour des personnes voulant savoir comment faire ceci en XML. C'est en fait assez simple. Ceci peut être accompli en utilisant un layer-list

Votre bouton est dessinable (drawable/some_button.xml):

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_pressed="true" Android:drawable="@drawable/some_button_highlighted" />
    <item Android:drawable="@drawable/some_button_image" />
</selector>

Et ceci est le dessin en surbrillance

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@drawable/some_button_image"/>
    <item>
        <shape>
            <solid Android:color="@color/highlighted_button_color" />
        </shape>
    </item>
</layer-list>

Vous pouvez maintenant l’utiliser dans n’importe quel autre fichier XML:

...
Android:drawable="@drawable/some_button"
...

J'espère que cela aidera quelqu'un à l'avenir. 

1
aeskreis

Ce que je fais est d'ajouter un bouton personnalisé qui a la fonction setColorFilter.

Comme cela, je peux utiliser le nouveau bouton dans le XML.

public class CustomButton extends Button {

public CustomButton(Context context) {
    super(context);
}

public CustomButton(Context context, AttributeSet attributes) {
    super(context, attributes);
};

@Override
public boolean onTouchEvent(MotionEvent event) {
    int maskedAction = event.getActionMasked();
    if (maskedAction == MotionEvent.ACTION_DOWN)
        getBackground().setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
    else if (maskedAction == MotionEvent.ACTION_UP)
        getBackground().setColorFilter(null);
    return super.onTouchEvent(event);
}}

et pour le ImageButton

public class CustomImageButton extends ImageButton {

public CustomImageButton(Context context) {
    super(context);
}

public CustomImageButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int maskedAction = event.getActionMasked();
    if (maskedAction == MotionEvent.ACTION_DOWN)
        setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
    else if (maskedAction == MotionEvent.ACTION_UP)
        setColorFilter(null);
    return super.onTouchEvent(event);
}}
1
Elisha Sterngold

Vous pouvez définir la couleur (teinte) à partir de XML. 

Définissez transparent (Android:background="@null") pour background puis utilisez tint:

<ImageButton
     Android:layout_width="wrap_content"
     Android:layout_height="fill_parent"
     Android:tint="@color/Amber_200"
     Android:background="@null"
     Android:src="@drawable/back_selector" />
0
user4813855