How to handle the Ripple effect on 9-patch and CardView, and have control over the states of the selector?
RippleDrawable
extends LayerDrawable
. Touch feedback drawable may contain multiple child layers, including a special mask layer that is not drawn to the screen. A single layer may be set as the mask by specifying its android:id
value as mask
. The second layer can be StateListDrawable
.
For example, here is our StateListDrawable
resource with name item_selectable.xml
:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="..." android:state_selected="true"/> <item android:drawable="..." android:state_activated="true"/> <item android:drawable="..." android:state_focused="true" android:state_pressed="true"/> <item android:drawable="..." android:state_pressed="true"/> <item android:drawable="..."/></selector>
To achieve ripple effect along with selectors we can set drawable above as a layer of RippleDrawable
with name list_selector_ripple.xml
:
<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/colorControlHighlight"> <item android:id="@android:id/mask"> <color android:color="@android:color/white"/> </item> <item android:drawable="@drawable/item_selectable"/></ripple>
UPD:
1) To use this drawable with CardView
just set it as android:foreground
, like this:
<android.support.v7.widget.CardView ... android:foreground="@drawable/list_selector_ripple" />
2) To make the ripple effect works within the bounds of the 9-patch we should set this 9-patch drawable as mask of ripple drawable (list_selector_ripple_nine_patch.xml
):
<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/colorControlHighlight"> <item android:id="@android:id/mask" android:drawable="@drawable/your_nine_patch" /> <item android:drawable="@drawable/your_nine_patch" /></ripple>
Then set the background of view:
<LinearLayout ... android:background="@drawable/list_selector_ripple_nine_patch" />
Simple way to create a ripple make a xml in drawable-v21 folder and use this code for xml.
android:backgroung="@drawable/ripple_xyz"
And if, Through java / dynamically use.
View.setBackgroundResource(R.drawable.ripple_xyz);
Here is the ripple_xyz.xml.
<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android"android:color="#228B22" >// ^ THIS IS THE COLOR FOR RIPPLE<item> <shape android:shape="rectangle" android:useLevel="false" > <solid android:color="#CCFFFFFF" />// ^ THIS IS THE COLOR FOR BACK GROUND </shape></item>
You have to set a mask layer in the ripple.
Something like this:
<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?attr/colorControlHighlight"> <item android:id="@id/mask"> <color android:color="@color/myColor" /> </item></ripple>