Material ripple effect hidden by other view in layout

Jukurrpa picture Jukurrpa · Aug 11, 2015 · Viewed 10.3k times · Source

I added a ripple effect on a ImageButton, however it is hidden by an ImageView used as a background for the parent view RelativeLayout.

Here's the layout file:

<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="172dp"
                android:orientation="vertical"
                android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
        android:id="@+id/drawerBackgroundImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/drawer_background"/>

    [...]

    <ImageButton
        android:id="@+id/drawerLogoutButton"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_alignBottom="@id/drawerEmailTextView"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:layout_marginRight="@dimen/activity_horizontal_margin"
        style="@style/FlatButtonStyle"
        android:scaleType="centerInside"
        android:src="@drawable/ic_logout_white_24dp"/>

</RelativeLayout>

(there's a bunch of other views but they're irrelevant here)

I'm using an ImageView as the background for the RelativeLayout as I need to set a specific scaleType for the image, so I can't use the basic android:background property.

The ripple effect is hidden as it doesn't have a mask layer (I want it to extend out of the button's bounds) and thus uses the ImageButton's parent view to be displayed. The effect is perfectly visible if I remove the ImageView.

Is there a way to get the ripple effect to be shown above the problematic ImageView?

Answer

Santiago Vanegas picture Santiago Vanegas · Jun 10, 2016

I had exactly the same issue and solved it using this thread: https://code.google.com/p/android/issues/detail?id=155880

Issue preview:

Before solved:

Before

After solved:

After

Explanation:

"Borderless buttons draw their content on the closest background. Your button might not be having background between itself and the ImageView, so it draws underneath the ImageView."

Solution:

"Use a transparent background (android:background="@android:color/transparent") on some layout containing the button (beneath the ImageView). This will dictate what the maximum bounds of the ripple effect is."

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                ...>

    <!-- Your background ImageView -->
    <ImageView
        android:id="@+id/drawerBackgroundImageView"
        android:src="@drawable/drawer_background"
        ... />

        <!-- ... -->

    <!-- HERE, you need a container for the button with the transparent
         background. Let's say you'll use a FrameLayout -->
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent">

        <!-- Maybe more items --> 

        <!-- Button with borderless ripple effect -->
        <ImageButton
            android:id="@+id/drawerLogoutButton"
            android:background="?selectableItemBackgroundBorderless"
            ... />

    </FrameLayout>

</FrameLayout>

Hope it helps.