PGMacDesign
PGMacDesign

Reputation: 6302

How do I keep a ripple effect within a view's bounds in a selector?

I am trying to figure out why my ripple effect is not conforming to the shape I have placed it in. Below is the code I am using:

This is the multi-purpose button that I am setting to the background of the ImageViews

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Enabled, Not Clicked -->
    <item
        android:state_enabled="true"
        android:state_pressed="false"
        android:drawable="@drawable/some_drawable_1"
        android:color="@color/Black"
        />

    <!-- Not Enabled, Not Clicked -->
    <item
        android:state_enabled="false"
        android:state_pressed="false"
        android:drawable="@drawable/some_drawable_1"
        android:color="@color/LightGrey"
        />

    <!-- Not Enabled, Clicked -->
    <item
        android:state_enabled="false"
        android:state_pressed="true"
        android:drawable="@drawable/some_drawable_1"
        android:color="@color/LightGrey"
        />

    <!-- Enabled, Clicked -->
    <item
        android:state_enabled="true"
        android:state_pressed="true"
        android:drawable="@drawable/the_drawable_I_am_working_on"
        android:color="@color/White"
        />
</selector>

And this is the drawable I am working on:

<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Ripple 1 -->
    <!-- Button -->
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid
                android:color="@color/colorPrimary" />
            <stroke
                android:width="1dp"
                android:color="@color/black" />
            <corners
                android:bottomLeftRadius="8dp"
                android:bottomRightRadius="8dp"
                android:topLeftRadius="8dp"
                android:topRightRadius="8dp" />

        </shape>
    </item>
    <!-- Ripple -->
    <item>
        <ripple xmlns:android="http://schemas.android.com/apk/res/android"
            android:color="@color/colorPrimaryDarkest" />
    </item>
</layer-list>

This code above produces this effect:

enter image description here

As you can see, it does two weird things, first, it does not stay within the boundaries of the button when the ripple completes (it ignores the rounded corners, this is the key to what I am trying to fix), and second, the first click never works right for some reason.

After reading up on it, the second attempt came from this link, Material effect on button with background color, where I changed the drawable to:

<?xml version="1.0" encoding="utf-8"?>
<!-- Ripple 2 -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="@color/colorPrimaryDarkest">
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid
                android:color="@color/colorPrimary" />
            <stroke
                android:width="1dp"
                android:color="@color/black" />
            <corners
                android:bottomLeftRadius="8dp"
                android:bottomRightRadius="8dp"
                android:topLeftRadius="8dp"
                android:topRightRadius="8dp" />

        </shape>
    </item>
</ripple>

This code above produces this effect:

enter image description here

As you can see in this version, although it has fixed the issue where it is now within the bounds, it no longer maintains the ripple effect; it mearly slowly converts the background color to the second color rather than producing an actual ripple effect.

Also, just to be clear here, I did also try moving the shape into its own drawable file (named testing2) and then referencing it like this:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDarkest">
    <item android:drawable="@drawable/testing2"/>
</ripple>

and it does the same thing.

Lastly, I have tried using the mask with this code:

<?xml version="1.0" encoding="utf-8"?>
<!-- Ripple 2 -->
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDarkest">
    <item
        android:id="@android:id/mask"
        android:drawable="@drawable/testing2" />
</ripple>

And the result is not at all what is desired as can be seen in this image:

enter image description here

It not only is not a ripple effect, it is a totally different color now (likely a blend of the two)

I have also tried the tips on the following other StackOverflow questions:

1) How to add a ripple effect on a layout with rounded corners?

2) How to create ripple effect in simple layout

3) Custom circle button

My question is, what am I missing in order to make a ripple drawable just like the first image, but one that works within the bounds of the shape?

Thanks all.

Upvotes: 2

Views: 2205

Answers (1)

Abushawish
Abushawish

Reputation: 1473

I finally got it:

I used this library: https://github.com/balysv/material-ripple.

Take the button (or any view) that you would like to have rounded ripple corners with, and wrap it with "com.balysv.materialripple.MaterialRippleLayout" in the XML, then ensure to add the rippleRoundedCorners and rippleOverlay attributes to that XML wrapper. It will look like this:

<com.balysv.materialripple.MaterialRippleLayout
    android:id="@+id/ripple"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:mrl_rippleOverlay="true"
    app:mrl_rippleRoundedCorners="18dp">
    <!-- Make sure the mrl_rippleRoundedCorners value is the same as the button's background's corner radius -->

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="Button inside a ripple"
    android:background="@drawable/rounded_background"/>

</com.balysv.materialripple.MaterialRippleLayout>

For the "mrl_rippleRoundedCorners" attribute in the wrapper, make sure its value is the same as the rounded corner radius in the button background.

Upvotes: 2

Related Questions