Search code examples
androidrippledrawable

Drawing ripple over view group content


I'm trying to apply a ripple effect (@drawable/pill) to a layout. The ripple draws under the layout children, while I'd like the effect to be applied over the content.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        android:background="@drawable/pill"
        android:padding="8dp">

        <ImageView
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/my_icon"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Sample text"/>
    </FrameLayout>

</FrameLayout>

And pill.xml (where @drawable/pill_bg is a custom shape):

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">
    <item android:id="@android:id/mask" android:drawable="@drawable/pill_bg"/>
    <item android:drawable="@drawable/pill_bg"/>
</ripple>

Following other posts, I tried applying android:background="@null" and android:drawSelectorOnTop="true" to the ImageView with no luck.

Does it even make sense to have the ripple defined as the background of a layout? I'm wondering if the right approach is to separate the ripple from the background drawable, and apply the ripple to a dummy view that overlaps the content.


Solution

  • You are right. What you have defined in the xml, works like as shown in the first diagram. To have the ripple drawable above the ImageView and TextView, you need to define it above them. One approach to achieve that would be to have an ImageView on top of your LinearLayout:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <LinearLayout
            android:id="@+id/ll_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true"
            android:padding="8dp">
    
            <ImageView
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/my_icon" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Sample text" />
        </LinearLayout>
    
        <ImageView
            android:id="@+id/iv_ripple"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@id/ll_container"
            android:layout_alignLeft="@id/ll_container"
            android:layout_alignRight="@id/ll_container"
            android:layout_alignTop="@id/ll_container"
            android:src="@drawable/pill" />
    
    </RelativeLayout>