Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to click views behind a Toolbar?

I have a toolbar with a transparent/translucent background that overlays the content. So, behind the toolbar, views can appear that are clickable. The problem is that they can not be clicked through the toolbar because the toolbar is catching the click event.

I tried setting android:clickable="false", android:focusable="false" and android:focusableInTouchMode="false" for the toolbar, but it has no effect. How can I send a click through the toolbar to the underlying view?

like image 339
Matthias Robbers Avatar asked May 24 '15 16:05

Matthias Robbers


2 Answers

Take a look at the implementation of Toolbar. It eats touch events, regardless of the clickable attribute.

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Toolbars always eat touch events, but should still respect the touch event dispatch
    // contract. If the normal View implementation doesn't want the events, we'll just silently
    // eat the rest of the gesture without reporting the events to the default implementation
    // since that's what it expects.

    final int action = MotionEventCompat.getActionMasked(ev);
    if (action == MotionEvent.ACTION_DOWN) {
        mEatingTouch = false;
    }

    if (!mEatingTouch) {
        final boolean handled = super.onTouchEvent(ev);
        if (action == MotionEvent.ACTION_DOWN && !handled) {
            mEatingTouch = true;
        }
    }

    if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
        mEatingTouch = false;
    }

    return true;
}

The solution is to extend from Toolbar and override onTouchEvent.

public class NonClickableToolbar extends Toolbar {

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return false;
    }
}
like image 141
Matthias Robbers Avatar answered Oct 06 '22 17:10

Matthias Robbers


Toolbar consumes all clicks. You need to subclass Toolbar, like @Matthias Robbens already mentioned.

If you still want to be able to set a click listener on the toolbar, use this:

/** Do not eat touch events, like super does. Instead map an ACTION_DOWN to a click on this 
 * view. If no click listener is set (default), we do not consume the click */
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_POINTER_DOWN){
        return performClick();
    }

    return false;
}
like image 25
Nino van Hooff Avatar answered Oct 06 '22 17:10

Nino van Hooff