How do I change the tint of an ImageButton on focus/press

Solution 1:

You can change the tint, quite easily in code via:

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

Hope it helps.

JS

Solution 2:

Here is how to do it using just xml. In your drawable folder create a selector. Eg: 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>

In my Image view in xml I set the android:tint attribute to the drawable created above.

android:tint = "@drawable/touch_selector"

The whole code looked like this:

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

This is an all xml solution, to put tint on an ImageView on press or on active. Similar can be done for ImageButton

Note that this only works for API level >= 21.

Solution 3:

Finally I have found a solution for 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));
}

May this help someone not to lose 2 hours !

Solution 4:

I found a way to do this in xml (in api 21 and up at least).

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

By setting the tint on the bitmap it's possible to reuse the same drawable in xml without having to intercept touches or subclass ImageView or ImageButton.

Once the selector has been created, just apply that as the src of the ImageView or ImageButton.

Solution 5:

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