Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Toasts get touch events on some phone, and not on others

Tags:

android

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 ?

like image 362
yoah Avatar asked Apr 24 '12 14:04

yoah


People also ask

How do I get touch event on android?

Try code below to detect touch events. mView. setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //show dialog here return false; } }); To show dialog use Activity method showDialog(int).

How are Android touch events delivered?

The touch event is passed in as a MotionEvent , which contains the x,y coordinates, time, type of event, and other information. The touch event is sent to the Window's superDispatchTouchEvent() .

How do you show toast messages on android?

Display the created Toast Message using the show() method of the Toast class. The code to show the Toast message: Toast. makeText(getApplicationContext(), "This a toast message", Toast.

Which method you should override to control your touch action?

To make sure that each view correctly receives the touch events intended for it, override the onInterceptTouchEvent() method.


1 Answers

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.

like image 123
theJosh Avatar answered Oct 07 '22 03:10

theJosh