7

I am using a Toast with a custom view. I instantiate the view and call setView on the toast. The Toast was supposed to float on top and not receive focus and touch events, and it worked well. After the app was launched, users complained that on a few phone models like the Galaxy Note, the Toast did get touch events and the app below it did not.

I printed the layout params flags (WindowManager.LayoutParams) that the view gets in method setLayoutParams. It turns out that on most devices, the value is 0x000098, but on some it is 0x040088. On the devices that the Toast gets the touch events, the flag FLAG_NOT_TOUCHABLE is removed, and the flag FLAG_WATCH_OUTSIDE_TOUCH is added. This explains why the toast gets the touch events.

But what causes this difference? Is there a way to force the toast to be not touchable ?

yoah
  • 7,180
  • 2
  • 30
  • 30
  • Did you find an answer? Also, how did you read the Toast params? – theJosh Feb 11 '15 at 00:15
  • Is "toast.getView().setEnabled(false);" working for you? That should disable touch events on the toast's view. – domi Feb 11 '15 at 00:30
  • This question is 2 years old and suddenly got back to life. I do not have a device to test this on at the moment – yoah Feb 11 '15 at 08:45
  • @domi I tried toast.getView().setEnabled(false) and it did not work. It sounded like a good try though. – theJosh Feb 11 '15 at 21:56
  • @theJosh I did not find an answer. I used SYSTEM_ALERT_WINDOW instead where I could set the flag explicitly. – yoah Feb 12 '15 at 17:18

1 Answers1

1

I have a work around. You need to have access to the view that the toast is covering. You can basically capture touch events going to the Toast. Then change the MotionEvent X and Y. Then send the MotionEvent to the view that is obscured. It feels a little hacky to me, but it works. I would think it would be better to change the flags on the Toast but I can't find them.

In the activity the creates the Toast:

final Taost toast = Toast.makeText(this, "Text", Toast.LENGTH_LONG);
final View myCoveredView = findViewById(R.id.my_covered_view);
final View toastView = toast.getView();

toastView.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(final View v2, final MotionEvent event) {
                    //Make sure the view is accessible
                    if(myCoveredView != null){
                        //Set the touch location to the absolute screen location
                        event.setLocation(event.getRawX(), event.getRawY());
                        //Send the touch event to the view
                        return myCoveredView.onTouchEvent(event);
                    } 
                    return false;
                }
            });

If anyone has a better way I would love to here it.

theJosh
  • 2,894
  • 1
  • 28
  • 50
  • For my case this is not good as the view below is of another app. You could try to get the view of the toast, find the window, and change the windows flags. I am not sure if these flags may be changed – yoah Feb 12 '15 at 18:00
  • Google uses a custom view in place of a normal toast in order to add the "undo" button in Gmail. Check out [this SO question](http://stackoverflow.com/questions/9575520/how-can-i-include-a-button-in-a-toast-notification) for more info. – sonictt1 Feb 17 '15 at 20:06