Reputation: 30143
I'm building a custom view that can optionally be clickable. I'd like to set a background that indicates the clickable state. Usually, I would do this with an XML Drawable implemented something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" android:state_enabled="false"/>
<item android:drawable="@drawable/background_white_grey_spinner_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/background_white_grey_spinner_normal"/>
</selector>
Unfortunately, it doesn't look like there's an android:state_clickable
or android:state_pressable
attribute. This seems like a weird oversight considering there's an android:state_long_pressable
. Am I missing something?
Upvotes: 1
Views: 1635
Reputation: 7635
State "enabled" itself is used when we want to set any drawable to the view when its clickable. So "state_enabled" is used to convey a particular view is clickable.
But we can also create a custom drawable state for a particular view and use it to define stateListDrawable
Please check the steps below to create custom drawable state for a view:
Create attrs.xml in res/values and add below code in it:
<resources>
<declare-styleable name="food">
<attr name="state_clickable" format="boolean" />
</declare-styleable>
</resources>
Create a Custom View which will honour custom drawable state. Adding a sample custom view class below.
We will have to override onCreateDrawableState
method and merge the existing drawable state with the new one.
class CustomButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : MaterialButton(context, attrs) {
private val STATE_CLICKABLE = intArrayOf(R.attr.state_clickable)
override fun onCreateDrawableState(extraSpace: Int): IntArray {
val drawableStates: IntArray = super.onCreateDrawableState(extraSpace + 1)
if (this.isClickable) {
mergeDrawableStates(drawableStates, STATE_CLICKABLE);
}
return drawableStates
}
}
Now we can make use of state_clickable in the stateListDrawable. Refer below:
Create a stateListDrawable in res/drawables/button_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/yourAppPackage">
<item
app:state_clickable="true"
android:drawable="@drawable/item_clickable" />
<item
app:state_clickable="false"
android:drawable="@drawable/item_non_clickable" />
</selector>
This drawable can now be used as background for custom view
Upvotes: 4
Reputation: 1274
You should combine states for single item:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" android:state_enabled="false"/>
<item android:drawable="@drawable/background_white_grey_spinner_pressed" android:state_enabled="true" android:state_pressed="true"/>
<item android:drawable="@drawable/background_white_grey_spinner_normal" android:state_enabled="true" android:state_pressed="false"/>
Upvotes: 2