Android, setting background color of button loses ripple effect

25,251

Solution 1

You can add the ripple effect & background color with an additionnal ripple drawable:

your layout :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button_connect"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dip"
        android:fontFamily="sans-serif"
        android:text="Connect"
        android:background="@drawable/ripple"
        android:textColor="#FFFFFF"
        android:textSize="18sp" />

</LinearLayout>

ripple.xml (this is where you can add background color in addition to the ripple effect) :

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

    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="?android:colorAccent" />
        </shape>
    </item>

    <item>
        <shape android:shape="rectangle">
            <!-- put your background color here-->
            <solid android:color="@color/default_color" />
        </shape>
    </item>

</ripple>

Solution 2

A very simple and straight forward way of doing this is to set ?attr/selectableItemBackground to android:foreground attribute of your button. Following xml is perfectly valid and works

<Button
    android:id="@+id/btn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:foreground="?attr/selectableItemBackground"/>

Solution 3

Don't change the background of Button. Change the theme.

<style name="ButtonGray">
    <item name="colorButtonNormal">@color/gray</item>
</style>

and in your xml file

<Button
     android:id="@+id/accept_button"
     android:layout_height="wrap_content"
     android:layout_width="0dp"
     android:layout_weight="1"
     android:text="@string/button_accept_group"
     android:theme="@style/ButtonGray"/>

Or you can add it in your main app theme

<style name="AppTheme"
           parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorButtonNormal">@color/primary_color</item>
</style>

And don't need change button background.

If you want totally custom background you need create your selector. And you can set there ripple effect.

Solution 4

Just use :

android:backgroundTint="#4CAF50"

Instead of:

android:background="#4CAF50"

Don't forget to change your Button to android.support.v7.widget.AppCompatButton

Solution 5

There was no answer for MaterialButton, so i will put it here.

For MaterialButton (com.google.android.material.button.MaterialButton), use 'backgroundTint' and 'rippleColor'.

<com.google.android.material.button.MaterialButton
    android:id="@+id/button_sign_in"
    android:layout_width="0dp"
    android:layout_height="55dp"
    app:backgroundTint="@android:color/white"
    app:rippleColor="?attr/colorControlHighlight"

?attr/colorControlHighlight is the default ripple color, you can change this value.

Share:
25,251
Tommy Saechao
Author by

Tommy Saechao

Updated on March 09, 2020

Comments

  • Tommy Saechao
    Tommy Saechao about 4 years

    After adding color to an android button, it loses its ripple effect that makes the user feel like there is a responsive click. How do I fix this? I've searched through many solutions but I couldn't find a definite one that wasn't ambiguous.

    <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=".ClockInOutFragment">
    
    
        <AnalogClock
            android:id="@+id/clock"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/date_and_time"/>
    
    
        <RelativeLayout
            android:id="@+id/date_and_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp">
    
            <TextView
                android:id="@+id/time_digits"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="12:10"
                android:textSize="45sp"/>
    
            <TextView
                android:id="@+id/am_pm"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@+id/time_digits"
                android:layout_toRightOf="@+id/time_digits"
                android:paddingLeft="3dp"
                android:text="PM"
                android:textSize="20sp"/>
    
            <TextView
                android:id="@+id/date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/time_digits"
                android:text="Mon, July 11"
                android:textSize="22sp"/>
        </RelativeLayout>
    
        <!--Clock in and out buttons-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:orientation="horizontal">
    
            <Button
                android:id="@+id/textView3"
                android:layout_width="0dp"
                android:layout_height="56dp"
                android:layout_weight="1"
                android:background="#4CAF50"
                android:gravity="center"
                android:text="Clock In"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#FFFFFF"/>
    
            <!--Divider between the clock in and out button-->
            <View
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:background="#B6B6B6"/>
    
            <Button
                android:id="@+id/textView4"
                android:layout_width="0dp"
                android:layout_height="56dp"
                android:layout_weight="1"
                android:background="#FF5252"
                android:gravity="center"
                android:text="Clock Out"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#FFFFFF"/>
        </LinearLayout>
    
    
    </RelativeLayout>
    
  • Wijay Sharma
    Wijay Sharma over 6 years
    how android differentiates which one is the mask and which one is the default color?
  • galcyurio
    galcyurio over 5 years
    Nice. However, backward compatibility is not supported under version 23.
  • Mehdi Dehghani
    Mehdi Dehghani about 5 years
    How to change the color of the effect?
  • Edgar Khimich
    Edgar Khimich over 4 years
    By id. For example - android:id="@android:id/mask"
  • user1228891
    user1228891 over 4 years
    This doesn't work for curved buttons using style="@style/Widget.AppCompat.Button.Colored" The result is the shadow has sharp corners, not curved corners.
  • SagaRock101
    SagaRock101 almost 4 years
    And this works for changing menu background with retaining ripple effect also
  • Konstantin Konopko
    Konstantin Konopko about 3 years
    This doesn't work with androidx.appcompat.widget.AppCompatButton
  • Konstantin Konopko
    Konstantin Konopko about 3 years
    Works good with Widget.AppCompat.Button.Borderless