38

I want to use ripple effects on Buttons. AppCompat v22.1 added AppCompatButton and new functionalities to AppCompat tinting.

My Layout:

<android.support.v7.widget.AppCompatButton
        android:id="@+id/add_remove_button"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:backgroundTint="@color/primary"
        android:textColor="@android:color/white"
        android:text="Remove" />

On my API 22 test device the ripple effect works perfectly, but i'm coding for API 11 and unfortunately backgroundTint needs API >= 21. How can i set the ripple effect to Buttons on older API versions?

Thomas Mohr
  • 666
  • 2
  • 8
  • 12
  • May be http://stackoverflow.com/questions/26444391/primary-dark-color-android-under-api-21 you can your answer here. – Hardy Apr 27 '15 at 08:25
  • Ripples don't work out of the box on pre-Lollipop, so you'll have to emulate them. – Egor Apr 27 '15 at 08:30
  • Ripple works only for api>=21 – Gabriele Mariotti Apr 27 '15 at 10:44
  • But according to http://android-developers.blogspot.hu/2015/04/android-support-library-221.html: "The full list of tint aware widgets at this time is: [...] AppCompatButton [...]" – hunyadym Apr 27 '15 at 17:00
  • 1
    Coloring a button works for me by applying a theme to the button having `colorButtonNormal` property (I tried 4.4.4 and 5.1). – hunyadym Apr 27 '15 at 18:48

4 Answers4

110

Just use app:backgroundTint instead of android:backgroundTint, the tint will take effect below Lollipop. The reason is AppCompatActivity AppCompatDelegateImplV7 use AppCompatViewInflater to auto change Button or TextView to AppCompatButton or AppCompatTextView, then app:backgroundTint take effect.

enter image description here

drakeet
  • 2,685
  • 1
  • 23
  • 30
  • 5
    And "app" is defined like this: xmlns:app="http://schemas.android.com/apk/res-auto" – jk7 May 19 '17 at 18:24
  • I have a linear layout on which i am using android:background="@drawable/background_sign_up" app:backgroundTint="#dd282d50" android:backgroundTintMode="multiply", what to do. – ashishdhiman2007 Jun 12 '17 at 11:12
  • Works but it says: "Unexpected namespace prefix “app” found for tag Button in app:backgroundTint line – CGR Nov 08 '17 at 18:26
  • 1
    For someone who get the error Unexpected namespace prefix “app” found for..., you might need to change Button to android.support.v7.widget.AppCompatButton – CGR Nov 08 '17 at 18:36
  • The AppCompatActivity changes the Buttons to AppCompatButton automatically, so you can ignore the warning – Florian Walther Aug 28 '18 at 15:20
  • programmatically on KitKat? – user924 Jun 04 '19 at 10:36
2

Ripples are not available as a build in functionality on Android <21. This is due to performance issues: devices with the new API can use the RenderThread which is not available to older devices. See also: http://android-developers.blogspot.de/2014/10/appcompat-v21-material-design-for-pre.html

Why are there no ripples on pre-Lollipop? A lot of what allows RippleDrawable to run smoothly is Android 5.0’s new RenderThread. To optimize for performance on previous versions of Android, we've left RippleDrawable out for now.

and_dev
  • 3,723
  • 1
  • 20
  • 28
1

To support ripple functionality below API 21 you may have to add a drawable in the background of your button:

<android.support.v7.widget.AppCompatButton
    android:id="@+id/add_remove_button"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/button_ripple"
    android:backgroundTint="@color/primary"
    android:textColor="@android:color/white"
    android:text="Remove" />

Then you have to add your xmls with the same name in both drawable and drawable-v21 directories (if you don't have them you may create and they will be automatically linked).

/res/drawable-v21/button_ripple.xml

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

/res/drawable/button_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="@color/white" />
        </shape>
    </item>
</selector>
1

I am sharing as my use case: it was with ImageView:

app:backgroundTint was not taking effect because I used android:src tag for the background image in that Imageview.

when I changed it to android:background for Imageview then app:backgroundTint worked perfectly.

2nd Use case as mentioned by different answers one should use

androidx.appcompat.widget.AppCompatImageView

instead of ImageView.