I have an imageview on which I have set a bitmap fetched from an url. On the imageview I have set an onClickListener which opens up a dialog.
I want to somehow change the tint (make it darker) when the imageview is pressed upon to provide a sort of button click like feel.
What do you suggest?
happydude's answer is the most elegant way to handle this but unfortunately (as pointed out in the comments) the source code for ImageView only accepts an integer (solid colour). Issue 18220 has been around for a couple years addressing this, I've posted a workaround there that I'll summarize here:
Extend ImageView and wrap drawableStateChanged() with code that sets the tint based on the new state:
TintableImageView.java
package com.example.widgets;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.support.v7.widget.AppCompatImageView;
import com.example.R;
public class TintableImageView extends AppCompatImageView {
private ColorStateList tint;
public TintableImageView(Context context) {
super(context);
}
public TintableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public TintableImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TintableImageView, defStyle, 0);
tint = a.getColorStateList(R.styleable.TintableImageView_tintColorStateList);
a.recycle();
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (tint != null && tint.isStateful())
updateTintColor();
}
private void updateTintColor() {
int color = tint.getColorForState(getDrawableState(), 0);
setColorFilter(color);
}
}
Define a custom attribute:
attrs.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="TintableImageView">
<attr name="tintColorStateList" format="reference|color" />
</declare-styleable>
</resources>
Use the widget and custom attribute with your local namespace instead of Android's:
example_layout.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.example.widgets.TintableImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/example"
android:clickable="true"
app:tintColorStateList="@color/color_selector"/>
</LinearLayout>
You can then use a colour selector like happydude suggested:
color_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="@color/pressed_color"/>
<item android:color="#00000000"/>
</selector>