Demonsoul Demonsoul - 10 months ago 79
Android Question

FAB Ripple effect persisting after touch

On all of my layouts, my FloatingActionButtons' ripple effects are persisting if the user lifts their finger outside of the FAB view. i.e. User presses down on white FAB, ripple happens turning FAB gray, user drags finger away from button and lifts it, and the button stays gray.

Here is a sample fab XML:


And all FABs are direct children of varying basic CoordinatorLayouts, i.e.


Tested on various devices ranging from Android 5.1 to Android 7.1, with the same issue on each.

I have not seen any similar occurrences on my other views as they respond to touch effects.

EDIT: Related Google Issue (see 'Issue #2')

Answer Source

I believe this is due to a fix merged to correct FloatingActionButton's clickable area in pre-Lollipop versions. This fix overrides the onTouchEvent() method to return false if the touch occurs outside of the content area. Unfortunately, this has the effect of stopping any further touch events being delivered to the View, so it never receives the ACTION_UP, and therefore does not update its pressed state accordingly.

We should be able to fix this fix by subclassing FloatingActionButton, overriding onTouchEvent() ourselves, doing the same area check, and setting the pressed state correctly if the event leaves the content area.

public class CustomFAB extends FloatingActionButton {

    private Rect mTouchArea = new Rect();

    public CustomFAB(Context c, AttributeSet a) {
        super(c, a);

    // Additional constructors as needed
    // ...

    public boolean onTouchEvent(MotionEvent ev) {
        if (getContentRect(mTouchArea) && !mTouchArea.contains((int) ev.getX(), (int) ev.getY())) {
        return super.onTouchEvent(ev);