How to use StateListDrawable
Posted on February 4, 2018 • 2 minutes • 333 words
Table of contents
What is a StateListDrawable?
Let’s say you have a View like a Button. You want to set a background to the button, you useandroid:background=”@drawable/ic_assignment_returned_black_24dp”
But what can you do when you want to set a different background while the button is pressed or maybe when the button is not focused anymore.
My first solution for this problem was to extend a View class and override the setPressed() method to set the specific drawables.
class MyToggleButton : android.support.v7.widget.AppCompatButton {
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs,
defStyleAttr) {
}
override fun setPressed(pressed: Boolean) {
if (pressed) {
background = resources.getDrawable(R.drawable.ic_assignment_turned_in_black_24dp)
} else {
background = resources.getDrawable(R.drawable.ic_assignment_returned_black_24dp)
}
}
}
In the fragment where i used the button I then called the method inside a onTouchListener()
btn2.setOnTouchListener { v, event ->
when {
event.action == MotionEvent.ACTION_DOWN -> btn2.isPressed=true
event.action == MotionEvent.ACTION_UP -> btn2.isPressed=false
}
true
}
This process can be simplified with StateListDrawables.
How do they work?
You just create a new xml file e.g. button_selector.xml inside your drawables folder.
<?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-auto">
<item android:drawable="@drawable/ic_assignment_turned_in_black_24dp" android:state_pressed="true"/>
<item android:drawable="@drawable/ic_assignment_returned_black_24dp"/>
</selector>
This selector will do the same like my custom view. The drawable from the item with android:state_pressed=“true” will be used when the button is pressed. You can use StateListDrawables also for other attributes like textColor. Android will use the item without a state as the default one.
Here is a list of all states that are available:
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"]
How to apply the selector?
You just use it like any other drawable inside your layout fileandroid:background="@drawable/button_selector"
Android will set the attributes when the view is in the specified state
And that’s it. Now you can apply this selector to any of your Views.