I am trying to update the tint of an ImageView programatically, and the colour I'm using is a selector that has different colours for when the view is enabled or disabled. When I try and use the suggested methods from other StackOverflow posts it set the enabled colour but does not update for views that are disabled
For example, I have the following four dots that are coloured red in XML, and I'm setting the bottom two to be green in code. The right two dots are disabled so I'd expect both to be the same disabled grey but as you can see the programatically set colour is always green
https://i.sstatic.net/tFpgp.png
How can I programatically update the tint of an ImageView so that it correctly follows the state in the selector?
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<!-- Also tried making these AppCompatImageViews -->
<ImageView
android:id="@+id/imgDot1"
android:layout_width="40dp"
android:layout_height="40dp"
android:tint="@color/color_red_stateful"
android:src="@drawable/ic_dot" />
<ImageView
android:id="@+id/imgDot2"
android:layout_width="40dp"
android:layout_height="40dp"
android:tint="@color/color_red_stateful"
android:src="@drawable/ic_dot" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imgDot3"
android:layout_width="40dp"
android:layout_height="40dp"
android:tint="@color/color_red_stateful"
android:src="@drawable/ic_dot" />
<ImageView
android:id="@+id/imgDot4"
android:layout_width="40dp"
android:layout_height="40dp"
android:tint="@color/color_red_stateful"
android:enabled="false"
android:src="@drawable/ic_dot" />
</LinearLayout>
imgDot2.isEnabled = false
imgDot4.isEnabled = false
// Tried each of these in turn
ImageViewCompat.setImageTintList(imgDot3, ColorStateList.valueOf(resources.getColor(R.color.color_green_stateful)))
ImageViewCompat.setImageTintList(imgDot4, ColorStateList.valueOf(resources.getColor(R.color.color_green_stateful)))
imgDot3.setColorFilter(ContextCompat.getColor(this, R.color.color_green_stateful))
imgDot4.setColorFilter(ContextCompat.getColor(this, R.color.color_green_stateful))
imgDot3.imageTintList = ColorStateList.valueOf(resources.getColor(R.color.color_green_stateful))
imgDot4.imageTintList = ColorStateList.valueOf(resources.getColor(R.color.color_green_stateful))
imgDot3.imageTintList = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_green_stateful))
imgDot4.imageTintList = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_green_stateful))
color_red_stateful.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#999"/>
<item android:color="#F00"/>
</selector>
color_green_stateful.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#999"/>
<item android:color="#0F0"/>
</selector>
ic_dot.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#000"
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"/>
</vector>
You are using getColor
method in every tried line, but this isn't proper, that's not color, that's selector
(color_red_stateful
and color_green_stateful
files). use Resources
or preferably ContextCompat
class and its useful method getColorStateList
ColorStateList colorStateList = ContextCompat.getColorStateList(this, R.color.your_color_selector);
this colorStateList
should be set as imageTintList
for desired ImageView
s
btw. after setting above you may use view.invalidate()
method for forcing immediate apply of changes (force redraw), but in most cases, also probably yours, this won't be needed