Android: How to prevent any touch events from being passed from a view to the one underneath it?

Android

Android Problem Overview


Specifically using the code below, is there a way to modify it so that the activity under this newly created view does not receive any gestures?

View v1 = new View(this);    
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
 1000,
 50,
 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
 PixelFormat.OPAQUE);

params.gravity = Gravity.BOTTOM;
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
wm.addView(v1, params);
	

Android Solutions


Solution 1 - Android

Add an onTouchEvent method to the view with top position then return true. True will tell the event bubbling that the event was consumed therefore prevent event from bubbling to other views.

protected boolean onTouchEvent (MotionEvent me) {
    return true;
}

For v1 you would do an import:

import android.view.View.OnTouchListener;

Then set the onTouchListener:

v1.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});

Solution 2 - Android

From code

View v1 = new View(this);   
v1.setClickable(true);
v1.setFocusable(true);

OR

From xml

<View
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="My button"
    android:focusable="true"
    android:clickable="true"/>

This will prevent touch and click events from being propagated to views that stay below your view.
Or if you inflate the View then to .xml add android:clickable="true"

Solution 3 - Android

You can do this too. You can set touch listener to child view and then in onTouch() event, you can block intercept touch event of parent.

i.e.

View v = findViewById(R.id.sample_view);
v.setOnTouchListener(new OnTouchListener() {
    // Setting on Touch Listener for handling the touch inside ScrollView
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    // Disallow the touch request for parent scroll on touch of child view
    v.getParent().requestDisallowInterceptTouchEvent(true);
    return false;
    }
});

Solution 4 - Android

You add a view like below, but make sure it is the last view you add to your xml. The last item in the xml is the item that lays on top of all the other views under it.

<View
        android:id="@+id/blocking_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#AA666666"
        android:clickable="true"
        android:focusable="true"
        android:visibility="visible"/>

Solution 5 - Android

all you need to do is just call

arg0.getParent().requestDisallowInterceptTouchEvent(true);

at the beginning of your onTouch function. Like thsi -

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        arg0.getParent().requestDisallowInterceptTouchEvent(true);
        switch(arg1.getActio){
        }
        
        return false; 

     }

Solution 6 - Android

I think the best approach is to add a touch event and set return value True

As you can see here:

  someView.setOnTouchListener(object: View.OnTouchListener {
        override fun onTouch(v: View?, event: MotionEvent?): Boolean{
            return true
        }

    })

returning True means that the top view is handling the touch and no need to hand over the touch event to other views related.

Solution 7 - Android

I'm a little late to the party but I don't think the accepted solution is very great. Here is a static method that accepts any number of views and disables this event bubbling. This has worked for me 100% of the time for API 17+ (lower untested)

public static void disableEventBubbling(View... views){
    for(View view : views){
        if(view != null){
            view.setOnTouchListener(new View.OnTouchListener(){
               @Override
                public boolean onTouch(View view, MotionEvent event){
                    view.getParent().requestDisallowInterceptTouchEvent(true);
                    return false;
                }
            });
        }
    }
}

You can add a case for whatever kind of event you want, or you could get rid of the switch and make the default case the only line inside the touch listener.

Solution 8 - Android

Just add a click delegate to the top view background, that will stop the views underneath receiving touches

linear_layout_background.Click += delegate
            {
                // Ensures views underneath does not receive touch events
            };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMindWireView Question on Stackoverflow
Solution 1 - AndroidJohn GiottaView Answer on Stackoverflow
Solution 2 - AndroidvovahostView Answer on Stackoverflow
Solution 3 - AndroidDhrumil PatelView Answer on Stackoverflow
Solution 4 - AndroidJeremiah EikenbergView Answer on Stackoverflow
Solution 5 - AndroidAkshay SahaiView Answer on Stackoverflow
Solution 6 - AndroidCodeRangerView Answer on Stackoverflow
Solution 7 - AndroidZachView Answer on Stackoverflow
Solution 8 - AndroidGustavo Baiocchi CostaView Answer on Stackoverflow