@@ -20,11 +20,12 @@ import android.view.MotionEvent
20
20
import android.view.View
21
21
import android.view.ViewGroup
22
22
import android.view.ViewStructure
23
- import android.view.Window
24
23
import android.view.WindowManager
25
24
import android.view.accessibility.AccessibilityEvent
26
25
import android.view.accessibility.AccessibilityNodeInfo
27
26
import android.widget.FrameLayout
27
+ import androidx.activity.ComponentDialog
28
+ import androidx.activity.OnBackPressedCallback
28
29
import androidx.annotation.UiThread
29
30
import androidx.core.view.WindowInsetsCompat
30
31
import androidx.core.view.WindowInsetsControllerCompat
@@ -49,10 +50,10 @@ import com.facebook.react.uimanager.ThemedReactContext
49
50
import com.facebook.react.uimanager.UIManagerModule
50
51
import com.facebook.react.uimanager.events.EventDispatcher
51
52
import com.facebook.react.views.common.ContextUtils
53
+ import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
52
54
import com.facebook.react.views.view.ReactViewGroup
53
55
import com.facebook.react.views.view.setStatusBarTranslucency
54
56
import com.facebook.react.views.view.setSystemBarsTranslucency
55
- import java.util.Objects
56
57
57
58
/* *
58
59
* ReactModalHostView is a view that sits in the view hierarchy representing a Modal view.
@@ -71,7 +72,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
71
72
ViewGroup (context), LifecycleEventListener {
72
73
73
74
@get:VisibleForTesting
74
- public var dialog: Dialog ? = null
75
+ public var dialog: ComponentDialog ? = null
75
76
private set
76
77
77
78
public var transparent: Boolean = false
@@ -260,17 +261,34 @@ public class ReactModalHostView(context: ThemedReactContext) :
260
261
}
261
262
262
263
val currentActivity = getCurrentActivity()
263
- val newDialog = Dialog (currentActivity ? : context, theme)
264
+ val newDialog = ComponentDialog (currentActivity ? : context, theme)
264
265
dialog = newDialog
265
- Objects .requireNonNull< Window > (newDialog.window)
266
- .setFlags(
267
- WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE ,
268
- WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE )
266
+ val window = requireNotNull (newDialog.window)
267
+ window .setFlags(
268
+ WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE ,
269
+ WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE )
269
270
270
271
newDialog.setContentView(contentView)
271
272
updateProperties()
272
273
273
274
newDialog.setOnShowListener(onShowListener)
275
+
276
+ val handleCloseAction: () -> Unit = {
277
+ val listener =
278
+ checkNotNull(onRequestCloseListener) {
279
+ " onRequestClose callback must be set if back key is expected to close the modal"
280
+ }
281
+ listener.onRequestClose(newDialog)
282
+ }
283
+
284
+ val backPressedCallback: OnBackPressedCallback =
285
+ object : OnBackPressedCallback (true ) {
286
+ override fun handleOnBackPressed () {
287
+ handleCloseAction()
288
+ }
289
+ }
290
+
291
+ newDialog.onBackPressedDispatcher.addCallback(newDialog, backPressedCallback)
274
292
newDialog.setOnKeyListener(
275
293
object : DialogInterface .OnKeyListener {
276
294
override fun onKey (dialog : DialogInterface , keyCode : Int , event : KeyEvent ): Boolean {
@@ -280,11 +298,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
280
298
// to whether or not to allow the back/escape key to close the dialog. If it chooses
281
299
// to, it can just set visible to false on the Modal and the Modal will go away
282
300
if (keyCode == KeyEvent .KEYCODE_BACK || keyCode == KeyEvent .KEYCODE_ESCAPE ) {
283
- val listener =
284
- checkNotNull(onRequestCloseListener) {
285
- " onRequestClose callback must be set if back key is expected to close the modal"
286
- }
287
- listener.onRequestClose(dialog)
301
+ handleCloseAction()
288
302
return true
289
303
} else {
290
304
// We redirect the rest of the key events to the current activity, since the
@@ -301,19 +315,19 @@ public class ReactModalHostView(context: ThemedReactContext) :
301
315
}
302
316
})
303
317
304
- newDialog. window? .setSoftInputMode(WindowManager .LayoutParams .SOFT_INPUT_ADJUST_RESIZE )
318
+ window.setSoftInputMode(WindowManager .LayoutParams .SOFT_INPUT_ADJUST_RESIZE )
305
319
if (hardwareAccelerated) {
306
- newDialog. window? .addFlags(WindowManager .LayoutParams .FLAG_HARDWARE_ACCELERATED )
320
+ window.addFlags(WindowManager .LayoutParams .FLAG_HARDWARE_ACCELERATED )
307
321
}
308
322
val flagSecureSet = isFlagSecureSet(currentActivity)
309
323
if (flagSecureSet) {
310
- newDialog. window? .setFlags(
324
+ window.setFlags(
311
325
WindowManager .LayoutParams .FLAG_SECURE , WindowManager .LayoutParams .FLAG_SECURE )
312
326
}
313
327
if (currentActivity?.isFinishing == false ) {
314
328
newDialog.show()
315
329
updateSystemAppearance()
316
- newDialog. window? .clearFlags(WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE )
330
+ window.clearFlags(WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE )
317
331
}
318
332
}
319
333
0 commit comments