After having been looking for a while I've not been able to find an answer to this...
I have a recycler view with items which when selected have a red background and white text (beforehand the background is white and text is black). To do this I am using a selector.
I have recently tried to add a ripple effect to this, but unless I long click on the item the background of the item goes straight to red without the ripple. I am assuming this is because the selector state state_selected overrides the ripple on sate_pressed?
Does anyone know if there is a way around this? Here is the selector code I use:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@android:color/holo_red_dark" >
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@drawable/ripple"
android:state_pressed="true"/>
<item
android:drawable="@android:color/holo_red_dark"
android:state_selected="true"/>
<item android:drawable="@android:color/white"/>
</selector>
</item>
</ripple>
Thanks in advance!
To create a selector background that has a ripple effect and shows selected status I do the following:
Start by defining your highlight color, with some transparency:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="selector_color">#660000ff</color>
</resources>
You probably want to have compatibility pre-lollipop. Put a typical old-school selector inside drawable folder:
- drawable/selector_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/selector_color" android:state_pressed="true"/>
<item android:drawable="@color/selector_color" android:state_selected="true"/>
<item android:drawable="@android:color/transparent"/>
</selector>
And then add the following layer drawable inside drawable-v21 folder:
- drawable-v21/selector_background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<selector>
<item android:state_selected="true"
android:drawable="@color/selector_color" />
<item android:drawable="@android:color/transparent" />
</selector>
</item>
<item>
<ripple android:color="@color/selector_color">
<item android:id="@android:id/mask">
<color android:color="@android:color/white" />
</item>
</ripple>
</item>
</layer-list>
Now you can use @drawable/selector_background
for your selector.
It will be better if you wrap your recyclerview item view in FrameLayout and set android:background="?selectableItemBackground" of FrameLayout and the child layout of FrameLayout background="@drawable/background"
background.xml
<item android:drawable="@color/red" android:state_selected="true"/>
<item android:drawable="@color/red" android:state_focused="true"/>
<item android:drawable="@color/red" android:state_pressed="true"/>
<item android:drawable="@color/white"/>
And then child layout must has attribute android:duplicateParentState="true"
So I have another case in which I had to use selector as well as layer list for that
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorRipple">
<item>
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/grey_very_light" />
</shape>
</item>
<!-- ripple color -->
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="@color/c_unread_notifications_item" />
</shape>
</item>
</layer-list>
</item>
</ripple>
</item>
<item>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorRipple">
<item>
<!-- ripple color -->
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/grey_very_light" />
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="@color/white" />
</shape>
</item>
</layer-list>
</item>
</ripple>
</item>
</selector>
This worked, for your need what you can do it just replace the item under ripple with your item shape if you don't have any layering.
Hope this helps