Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material ripple effect hidden by other view in layout

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?

like image 622
Jukurrpa Avatar asked Aug 11 '15 17:08

Jukurrpa


2 Answers

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.

like image 123
Santiago Vanegas Avatar answered Oct 06 '22 01:10

Santiago Vanegas


I am experiencing same issue. Only solution I have found so far is not 100% okay since ripple is masked by view (its not borderless).

The solution (workaround): surround your ImageButton with other view and set ripple to the foreground instead of the background in your layout like this:

<ImageView ... /> 

<FrameLayout
    ...
    android:clickable="true"
    android:focusable="true"
    android:foreground="?attr/selectableItemBackgroundBorderless" >

    <ImageButton />
</FrameLayout>

I would be really glad if someone explain why the ripple is drawn behind the image. Also if you look at Google Photos app, in image detail they have transparent icons over image view with ripple. I would like to replicate this, but I am not able to make the ripple to be in foreground. Does anybody know how to put transparent imagebuttons over everything but still have the ripple?

EDIT final solution here you can find exactly same question link

with great explanation what is happening. the solution is the same but on top of that it solves rectangular mask by adding

android:clipChildren="false"
android:clipToPadding="false"

to your layout. now your ripple should be borderless (it worked for me). The layout xml could be something like this:

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

    <ImageView ... /> 

    <FrameLayout
        ...

        android:clickable="true"
        android:foreground="?attr/selectableItemBackgroundBorderless">
       <ImageView ... />
    </FrameLayout>

</FrameLayout>
like image 43
Marek Salát Avatar answered Oct 06 '22 01:10

Marek Salát