How to create ripple effect in simple layout
Asked Answered
R

11

154

How can I have a ripple effect in a simple linear/relative layout when touching the layout?

I've tried setting the background of a layout to something like:

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

    <item android:drawable="@android:color/white"/>

</ripple>

However I'm only seeing a plain white background and no ripple effect when touching the layout. What am I doing wrong?

Edit:

For reference, here is my layout xml file:

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:background="@drawable/test"
        android:clickable="true">
    </RelativeLayout>
Readability answered 18/11, 2014 at 23:38 Comment(4)
The view hosting the ripple needs to be enabled and clickable or focusable.Joappa
Thanks Alanv, see below for my response. Basically I am marking my layout I want to have the ripple effect in as clickable, but it does not work still.Readability
Also, this works fine if I remove the <item android:drawable="@android:color/white"/> section. So I'm not sure how this is supposed to work if I wanted a background color on the layout. Laying this on top of another layout with a background color also does not work!Readability
What color is the ripple being drawn in your view, e.g. what color does colorControlHighlight resolve to?Joappa
R
26

It turns out this is working as intended. The standard Material theme colorControlHighlight value is #40ffffff. So on a white background, this will not show up. Changing the highlight color to something else works, and/or changing the background color of the object.

Thanks all (especially Alanv for pointing me in the right direction).

Readability answered 20/11, 2014 at 15:56 Comment(3)
if I'm using android:background="?attr/selectableItemBackground" on my view how can I change the background of the object?Quaff
Nevermind I found that the selectableItemBackground default state is transparent. So, I set a view under it with the color I wanted.Quaff
quick note: you can change colorControlHighlight in your styles.xml. Add it to your custom theme for instance.Marketing
S
328

Set these properties on your layout (if your layout has the default white/light background):

          android:clickable="true"
          android:focusable="true"
          android:background="?attr/selectableItemBackground"

You don't need a custom drawable in this case.

However, if your layout has a black/dark background, you'd have to create your own ripple drawable like this one:

<?xml version="1.0" encoding="utf-8"?>
<!-- An white rectangle ripple. -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@android:color/white">
    <item
        android:id="@android:id/mask"
        android:gravity="center">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white"/>
        </shape>
    </item>
</ripple>

And then set this ripple drawable as your android:background property.

You can see many examples of these types of ripples in AOSP: in here

Schizophyceous answered 2/10, 2015 at 18:32 Comment(11)
what if i have to give different color as background ? Then what should be the best approach ?Donnelldonnelly
@AnujSharma Have you tried giving color resource for background?Schizophyceous
yes i tried that, in case i need to add ripple xml in drawable folder, i thought i can use this single line to generate ripple effectDonnelldonnelly
@ralphspoon See #26604634Schizophyceous
@AnujSharma you can create a drawable with color and ripple efect and give it as a background to your layout.Dam
If you'd like another background color you can set that color as background and put "?attr/selectableItemBackground" as android:foreground insteadCarse
@Schizophyceous now the error has gone but no ripple. nothing happens when I clickKaftan
Keep in mind you also have the option to use android:background="?attr/selectableItemBackgroundBorderless" With it being border less The ripple effect will extend out to the parent view. This may look better in many cases.Smoker
Beware that the foreground attribute has been added in API 23 (Android 6.0) and has no effect on API levels lower than 23 (as per Android Studio warning)Ungotten
@flawyte Correct, however the foreground attribute is available on a FrameLayout below API v23, I think down to v16.Huntlee
@MattMc I believe it's been available on FrameLayout since API 1, however there's a better solution than wrapping your ImageView in an additional container just to add a ripple.Ungotten
D
70

I'm adding this in addition to Igor Ganapolsky's answer in case anyone wants to have a layout with different color and also have a ripple effect. You simply create a ripple effect in drawables like this:

ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/rippleColor"
    tools:targetApi="lollipop"> <!-- ripple effect color -->
    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <solid android:color="@color/backgroundColor" /> <!-- background color -->
        </shape>
    </item>
</ripple>

then give it as your layout's background or any button as Igor Ganapolsky mentioned in his answer.

android:clickable="true"
android:background="@drawable/ripple"
Dam answered 16/8, 2016 at 20:46 Comment(0)
A
52

You have to alter following code snippet in any widget(TextView/Button) and you can implement Ripple Effect:

android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"

And you are good to go.

Allowed answered 11/10, 2017 at 5:8 Comment(9)
hmm foreground? this is great!Tontine
This is helpful if you already have a android:background="@color/colorAccent" setThera
@Thera It is helpful, even if you don't set any background.Allowed
this works on layouts and custom views in addition to widgets.Baksheesh
Keep in mind you also have the option to use android:background="?attr/selectableItemBackgroundBorderless" With it being border less The ripple effect will extend out to the parent view. This may look better in many cases.Smoker
@MichaelKern Yes, you're right, also it is based upon everybody's requirement in their code.Allowed
Beware that the foreground attribute has been added in API 23 (Android 6.0) and has no effect on API levels lower than 23 (as per Android Studio warning)Ungotten
@flawyte Correct, however the foreground attribute is available on a FrameLayout below API v23, I think down to v16.Huntlee
@MattMc I believe it's been available on FrameLayout since API 1, however there's a better solution than wrapping your ImageView in an additional container just to add a ripple.Ungotten
R
26

It turns out this is working as intended. The standard Material theme colorControlHighlight value is #40ffffff. So on a white background, this will not show up. Changing the highlight color to something else works, and/or changing the background color of the object.

Thanks all (especially Alanv for pointing me in the right direction).

Readability answered 20/11, 2014 at 15:56 Comment(3)
if I'm using android:background="?attr/selectableItemBackground" on my view how can I change the background of the object?Quaff
Nevermind I found that the selectableItemBackground default state is transparent. So, I set a view under it with the color I wanted.Quaff
quick note: you can change colorControlHighlight in your styles.xml. Add it to your custom theme for instance.Marketing
A
15

This is an example for clicking on a sample layout with ripple effect :

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    android:orientation="vertical">
Adipose answered 11/2, 2019 at 10:55 Comment(1)
That's simple awesome how simple this is and the simple fact that this simply Just Works™.Forsaken
P
9

Set android:clickable="true" on your layout.

Pantaloons answered 19/11, 2014 at 10:11 Comment(0)
M
6
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#cfd8dc"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#d1c4e9" />
        </shape>
    </item>
</ripple>

Use this ripple.xml in Drawable folder, then assign it as View's

android:background="@drawable/ripple"

android:clickable="true"

Mande answered 7/8, 2018 at 7:39 Comment(0)
B
2

Simply add default ripple effect with android:background="?selectableItemBackground"

Like:

<LinearLayout
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="?selectableItemBackground"
            android:clickable="true"
            >

           ...

</LinearLayout>
Billups answered 23/2, 2018 at 16:19 Comment(0)
P
0

Put this into your layout:

android:clickable="true"
android:background="?attr/selectableItemBackground"

Note: There is a bug in API documentation. It will work only on API >= 23

For all API levels use this Solution

Phile answered 29/9, 2016 at 7:12 Comment(2)
Your link redirect this same pageKaftan
Keep in mind you also have the option to use android:background="?attr/selectableItemBackgroundBorderless" With it being border less The ripple effect will extend out to the parent view. This may look better in many cases.Smoker
G
0

I tries all those answers and nothing worked to me, so, I solved creating the following style:

<style name="Button.Borderless" parent="Base.Widget.AppCompat.Button.Borderless">
    <item name="android:minHeight">0dp</item>
    <item name="android:minWidth">0dp</item>
    <item name="android:layout_marginLeft">-6dp</item>
    <item name="android:layout_marginRight">-6dp</item>
    <item name="android:paddingTop">0dp</item>
    <item name="android:paddingBottom">0dp</item>
    <item name="android:paddingLeft">6dp</item>
    <item name="android:paddingRight">6dp</item>
</style>

And then, I applied to my linear layout:

<LinearLayout
      android:id="@+id/ll_my_ripple"
      style="@style/Button.Borderless">
</LinearLayout>
Glendaglenden answered 3/4, 2018 at 19:7 Comment(0)
O
0

To make a circlar effect use the below code:

android:clickable="true"
android:background="?attr/selectableItemBackgroundBorderless"
Officiant answered 4/10, 2022 at 8:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.