Skip to content

Instantly share code, notes, and snippets.

@yongjhih
Last active December 3, 2023 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yongjhih/2a9d0bf1be8a0d15d2181b8706750a81 to your computer and use it in GitHub Desktop.
Save yongjhih/2a9d0bf1be8a0d15d2181b8706750a81 to your computer and use it in GitHub Desktop.
/**
* See Also: BackHandler { onBack() }
*/
@Composable
fun BackCompatHandler(
enabled: Boolean = true,
onBack: () -> Unit = {}
) {
val currentOnBack by rememberUpdatedState(onBack)
val backCallback = remember {
object : OnBackPressedCallback(enabled) {
override fun handleOnBackPressed() {
currentOnBack()
}
}
}
SideEffect {
backCallback.isEnabled = enabled
}
val localOnBackPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
val view = LocalView.current
val lifecycleOwner = LocalLifecycleOwner.current
val context = LocalContext.current
val backPressedDispatcher =
(((lifecycleOwner as? DialogFragment)
?: (view.ancestorFragments.filterIsInstance<DialogFragment>().firstOrNull()))
?.dialog as? ComponentDialog)?.onBackPressedDispatcher
?: localOnBackPressedDispatcherOwner?.onBackPressedDispatcher
?: ((lifecycleOwner as? ComponentActivity)
?: (lifecycleOwner as? Fragment)?.activity as? ComponentActivity
?: context as? ComponentActivity
?: context.activity as? ComponentActivity)?.onBackPressedDispatcher
if (enabled) {
backPressedDispatcher?.addCallback(lifecycleOwner, backCallback)
}
LaunchedEffect(enabled) {
if (!enabled) { backCallback.remove() }
}
DisposableEffect(lifecycleOwner.lifecycle, backPressedDispatcher) {
onDispose { backCallback.remove() }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment