Home » Android » android – How does the PopupWindow get notified of touched outside events?

android – How does the PopupWindow get notified of touched outside events?

Posted by: admin June 15, 2020 Leave a comment

Questions:

The documentation states that PopupWindow will be informed of touch events outside of its window when
setOutsideTouchable(boolean touchable) is set to true.
How is popupwindow informed? I don’t see any listener like setOnOutsideTouchListener etc to receive that information.

Example

PopupWindow popup = new PopupWindow();
popup.setOutsideTouchable(true);
//now what..how to receive those touch outside events?

Thanks.

How to&Answers:

try to use setTouchInterceptor like the following snipt of code

popup.setTouchInterceptor(new OnTouchListener() 
    {

        public boolean onTouch(View v, MotionEvent event) 
        {
            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) 
            {
                popup.dismiss();
                return true;
            }

            return false;
        }
    });

also don’t forget to set thew following flag:

popup.setOutsideTouchable(true);

Answer:

When you touch outside the PopupWindow, OnDismissListener is triggered as touching outside window dismisses the window by default, so you can set OnDismissListener on popupWindow to listen to touch outside the window.

popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {
         //Do Something here
    }
});

Answer:

“The popup window is a floating container that appears on top of the
current activity.”

See: https://developer.android.com/reference/android/widget/PopupWindow.html

I think this is what you are looking for.

Answer:

PopupWindow notified on outside touch events same way as on all other touch events. When flag is set outside events routed to popup and you can handle them same way as you handle touches. There is no special method to test that this outside event or set listener for events of such kind. If you check source code:

1341        @Override
1342        public boolean dispatchTouchEvent(MotionEvent ev) {
1343            if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
1344                return true;
1345            }
1346            return super.dispatchTouchEvent(ev);
1347        }
1348
1349        @Override
1350        public boolean onTouchEvent(MotionEvent event) {
1351            final int x = (int) event.getX();
1352            final int y = (int) event.getY();
1353            
1354            if ((event.getAction() == MotionEvent.ACTION_DOWN)
1355                    && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
1356                dismiss();
1357                return true;
1358            } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
1359                dismiss();
1360                return true;
1361            } else {
1362                return super.onTouchEvent(event);
1363            }
1364        }

Now you can see that PopupWindow itself checks that an event’s X/Y are outside and dismisses itself. So you can set TouchInterceptor to catch event before or instead default handler. Or you can Override onTouchEvent to do your own event handling and call super if it make sense for you.

Answer:

补充:
In my case,if i click the EditText outside the popupWindow,
If setFocusable(true),event.getAction()==0(So I have to double click the editText to input.)
If setFocusable(false,event.getAction()==4(MotionEvent.ACTION_OUTSIDE).(click one time,and i can input)