PopupWindow thông báo về các sự kiện liên lạc bên ngoài cùng một cách như trên tất cả các các sự kiện liên lạc khác. Khi cờ được đặt bên ngoài các sự kiện được định tuyến đến cửa sổ bật lên và bạn có thể xử lý chúng giống như cách bạn xử lý các lần chạm. Không có phương pháp đặc biệt nào để kiểm tra sự kiện bên ngoài này hoặc đặt người nghe cho các sự kiện thuộc loại đó. Nếu bạn kiểm tra mã nguồn:
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 }
Bây giờ bạn có thể thấy rằng PopupWindow tự kiểm tra xem X/Y của sự kiện có nằm ngoài và loại bỏ chính nó hay không. Vì vậy, bạn có thể thiết lập TouchInterceptor để bắt sự kiện trước hoặc thay vào đó xử lý mặc định. Hoặc bạn có thể ghi đè onTouchEvent để xử lý sự kiện của riêng bạn và gọi siêu nếu nó có ý nghĩa với bạn.
Để thêm vào điều này, các phương thức hiển thị .. (showAtLocation hoặc ShowAsDropDown) nên được gọi là SAU câu trả lời ở trên và không ở giữa. – Thupten
'if (event.getAction() == MotionEvent.ACTION_OUTSIDE) 'luôn luôn không đúng như mọi khi nó là MotionEvent.ACTION_DOWN, và do đó giải pháp này không hoạt động, giải pháp tốt hơn là đặt OnDismissListener sẽ được gọi mỗi khi bạn nhấp vào bên ngoài cửa sổ. Tôi đã thêm câu trả lời này làm câu trả lời –