Cómo puedo cambiar el tinte de un botón de imagen en focus / press


Tengo un ImageButton en mi aplicación y necesito cambiar el tinte de la imagen cuando el botón es pressed/focused. Tengo el ImageButton establecido para obtener su src de un archivo XML que de la siguiente manera:

<?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>

Sin embargo, el tinte no se aplica cuando se presiona o enfoca ImageButton, la imagen simplemente se muestra como normal. El color negro se define como #000000 como siempre. Alguna idea?

Author: Sami Eltamawy, 2010-06-11

9 answers

Puede cambiar el tinte, bastante fácilmente en el código a través de:

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

Espero que ayude.

JS

 74
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-03 14:06:30

Finalmente he encontrado una solución para API

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));
}

Que esto ayude a alguien a no perder 2 horas !

 6
Author: Henrique de Sousa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-11 10:08:44

Encontré una manera de hacer esto en xml (al menos en api 21 y superiores).

<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>

Al establecer el tinte en el mapa de bits, es posible reutilizar el mismo elemento de diseño en xml sin tener que interceptar toques o subclases ImageView o ImageButton.

Una vez creado el selector, simplemente aplíquelo como el src de ImageView o ImageButton.

 4
Author: ckern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-07 19:22:19

Aquí está cómo hacerlo usando solo xml. En tu carpeta de elementos de diseño, crea un selector. Por ejemplo: 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>

En mi vista de imagen en xml establecí el atributo android:tint en el elemento de diseño creado anteriormente.

android:tint = "@drawable/touch_selector"

Todo el código se veía así:

<?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" />

Esta es una solución todo xml, para poner tinte en una ImageView en prensa o en activo. Similar can be done for ImageButton

Tenga en cuenta que esto solo funciona para el nivel de API >= 21.

 4
Author: Rashi Karanpuria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-23 16:31:52
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
Author: Fu-Lung Chen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-15 06:49:51

Lo que estoy haciendo es agregar un botón personalizado que tiene la función setColorFilter.

Así puedo usar el botón nuevo en el 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);
}}

Y para el botón 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
Author: Elisha Sterngold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-24 14:03:06

He notado que hay algunas solicitudes aquí para personas que quieren saber cómo hacer esto en XML. En realidad es bastante simple. Esto se puede lograr usando un layer-list

El elemento de diseño de tu botón (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>

Y este es el elemento de diseño resaltado (drawable/some_button_highlighted.xml)

<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>

Ahora puede usar esto en cualquier otro xml:

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

Espero que esto ayude a alguien en el futuro.

 1
Author: aeskreis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-23 19:35:35

Puede establecer el color (tinte) desde xml.

Conjunto transparent (android:background="@null") para background entonces use 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
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-29 05:09:12

Como ha definido el selector para ser el src de la ImageButton Android AFAIK solo tendrá el elemento de diseño porque eso es lo que coincide con el tipo de src. Así que no se usará tinte.

Sin embargo, tuve un problema similar: también traté de usar un selector como el tuyo, pero para el valor android:tint del botón ImageButton en lugar de android:src. Por supuesto, omití los valores de tinte que tiene en su selector. Esto también resolvería tu problema, porque quieres usar el mismo elemento de diseño para todos estado. Curiosamente, recibo una excepción NumberFormatException cada vez que indica que el sistema no pudo analizar 'res/color/tint_selector.xml ' (que es de hecho mi selector) como entero. Para ser específico, mi código se ve así:

Este es mi selector, guardado en /res/color/tint_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_pressed="true"
         android:color="#D3D3D3"/> <!-- pressed -->
   <item android:color="#ff000000"/> <!-- default -->
</selector>

Y este es el botón de imagen correspondiente:

<ImageButton android:id="@+id/program_help"
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"
     android:src="@drawable/symbol"
     android:tint="@color/tint_selector">
</ImageButton>

Tal vez esto te ayude un poco, aunque actualmente no funciona.

 -3
Author: ubuntudroid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-25 17:15:27