2222import android .os .Build .VERSION_CODES ;
2323import androidx .annotation .RestrictTo ;
2424import androidx .annotation .RestrictTo .Scope ;
25- import androidx .appcompat .app .AlertDialog ;
2625import android .view .MotionEvent ;
2726import android .view .View ;
2827import android .view .View .OnTouchListener ;
28+ import android .view .ViewConfiguration ;
2929
3030/**
31- * Ensures that touches within the transparent region of the inset drawable used for Dialogs
32- * are processed as touches outside the Dialog.
31+ * Ensures that touches within the transparent region of the inset drawable used for Dialogs are
32+ * processed as touches outside the Dialog.
3333 *
3434 * @hide
35- *
3635 */
3736@ RestrictTo (Scope .LIBRARY_GROUP )
3837public class InsetDialogOnTouchListener implements OnTouchListener {
3938
4039 private final Dialog dialog ;
4140 private final int leftInset ;
4241 private final int topInset ;
42+ private final int prePieSlop ;
4343
44- public InsetDialogOnTouchListener (AlertDialog dialog , Rect insets ) {
45- this .dialog = dialog ;
46- this .leftInset = insets .left ;
47- this .topInset = insets .top ;
48- }
49-
50- public InsetDialogOnTouchListener (android .app .AlertDialog dialog , Rect insets ) {
44+ public InsetDialogOnTouchListener (Dialog dialog , Rect insets ) {
5145 this .dialog = dialog ;
5246 this .leftInset = insets .left ;
5347 this .topInset = insets .top ;
48+ this .prePieSlop = ViewConfiguration .get (dialog .getContext ()).getScaledWindowTouchSlop ();
5449 }
5550
5651 @ Override
@@ -68,13 +63,13 @@ public boolean onTouch(View view, MotionEvent event) {
6863 }
6964 MotionEvent outsideEvent = MotionEvent .obtain (event );
7065 outsideEvent .setAction (MotionEvent .ACTION_OUTSIDE );
71- // Window.shouldCloseOnTouch does not respect MotionEvent.ACTION_OUTSIDE until Pie
72- view .performClick ();
73- if (VERSION .SDK_INT >= VERSION_CODES .P ) {
74- return dialog .onTouchEvent (outsideEvent );
75- } else {
76- dialog .onBackPressed ();
77- return true ;
66+ // Window.shouldCloseOnTouch does not respect MotionEvent.ACTION_OUTSIDE until Pie, so we fix
67+ // the coordinates outside the view and use MotionEvent.ACTION_DOWN
68+ if (VERSION .SDK_INT < VERSION_CODES .P ) {
69+ outsideEvent .setAction (MotionEvent .ACTION_DOWN );
70+ outsideEvent .setLocation (-prePieSlop - 1 , -prePieSlop - 1 );
7871 }
72+ view .performClick ();
73+ return dialog .onTouchEvent (outsideEvent );
7974 }
8075}
0 commit comments