@@ -20,11 +20,12 @@ import android.view.MotionEvent
2020import android.view.View
2121import android.view.ViewGroup
2222import android.view.ViewStructure
23- import android.view.Window
2423import android.view.WindowManager
2524import android.view.accessibility.AccessibilityEvent
2625import android.view.accessibility.AccessibilityNodeInfo
2726import android.widget.FrameLayout
27+ import androidx.activity.ComponentDialog
28+ import androidx.activity.OnBackPressedCallback
2829import androidx.annotation.UiThread
2930import androidx.core.view.WindowInsetsCompat
3031import androidx.core.view.WindowInsetsControllerCompat
@@ -49,10 +50,10 @@ import com.facebook.react.uimanager.ThemedReactContext
4950import com.facebook.react.uimanager.UIManagerModule
5051import com.facebook.react.uimanager.events.EventDispatcher
5152import com.facebook.react.views.common.ContextUtils
53+ import com.facebook.react.views.modal.ReactModalHostView.DialogRootViewGroup
5254import com.facebook.react.views.view.ReactViewGroup
5355import com.facebook.react.views.view.setStatusBarTranslucency
5456import com.facebook.react.views.view.setSystemBarsTranslucency
55- import java.util.Objects
5657
5758/* *
5859 * ReactModalHostView is a view that sits in the view hierarchy representing a Modal view.
@@ -71,7 +72,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
7172 ViewGroup (context), LifecycleEventListener {
7273
7374 @get:VisibleForTesting
74- public var dialog: Dialog ? = null
75+ public var dialog: ComponentDialog ? = null
7576 private set
7677
7778 public var transparent: Boolean = false
@@ -260,17 +261,34 @@ public class ReactModalHostView(context: ThemedReactContext) :
260261 }
261262
262263 val currentActivity = getCurrentActivity()
263- val newDialog = Dialog (currentActivity ? : context, theme)
264+ val newDialog = ComponentDialog (currentActivity ? : context, theme)
264265 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 )
269270
270271 newDialog.setContentView(contentView)
271272 updateProperties()
272273
273274 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)
274292 newDialog.setOnKeyListener(
275293 object : DialogInterface .OnKeyListener {
276294 override fun onKey (dialog : DialogInterface , keyCode : Int , event : KeyEvent ): Boolean {
@@ -280,11 +298,7 @@ public class ReactModalHostView(context: ThemedReactContext) :
280298 // to whether or not to allow the back/escape key to close the dialog. If it chooses
281299 // to, it can just set visible to false on the Modal and the Modal will go away
282300 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()
288302 return true
289303 } else {
290304 // We redirect the rest of the key events to the current activity, since the
@@ -301,19 +315,19 @@ public class ReactModalHostView(context: ThemedReactContext) :
301315 }
302316 })
303317
304- newDialog. window? .setSoftInputMode(WindowManager .LayoutParams .SOFT_INPUT_ADJUST_RESIZE )
318+ window.setSoftInputMode(WindowManager .LayoutParams .SOFT_INPUT_ADJUST_RESIZE )
305319 if (hardwareAccelerated) {
306- newDialog. window? .addFlags(WindowManager .LayoutParams .FLAG_HARDWARE_ACCELERATED )
320+ window.addFlags(WindowManager .LayoutParams .FLAG_HARDWARE_ACCELERATED )
307321 }
308322 val flagSecureSet = isFlagSecureSet(currentActivity)
309323 if (flagSecureSet) {
310- newDialog. window? .setFlags(
324+ window.setFlags(
311325 WindowManager .LayoutParams .FLAG_SECURE , WindowManager .LayoutParams .FLAG_SECURE )
312326 }
313327 if (currentActivity?.isFinishing == false ) {
314328 newDialog.show()
315329 updateSystemAppearance()
316- newDialog. window? .clearFlags(WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE )
330+ window.clearFlags(WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE )
317331 }
318332 }
319333
0 commit comments