В наших предыдущих статьях мы обсуждали устаревание метода onBackPressed и появление onBackPressedDispatcher в библиотеке Android Jetpack Compose. По мере того, как мы продолжаем изучать новые функции и изменения в Jetpack Compose, важно понимать, как справляться с нажатиями в обратном направлении из непосредственно компонуемых объектов. В этой статье мы углубимся в детали того, как обрабатывать обратное нажатие из непосредственно компонуемых объектов, и предложим обходной путь для нового OnBackInvokedCallback. Независимо от того, являетесь ли вы опытным разработчиком Android или только начинаете работать с Jetpack Compose, эта статья предоставит ценную информацию и методы управления нажатиями на кнопку в компонуемом пользовательском интерфейсе.
Прежде всего, мы начнем с того, как обращаться с обратными нажатиями в составных. Как вы, возможно, знаете, у нас есть OnBackPressedCallback
, который используется для получения обратных вызовов обратных нажатий. Обратный вызов
Прежде всего, мы начнем с того, как обращаться с обратными нажатиями в составных. Как вы, возможно, знаете, у нас есть OnBackPressedCallback, который используется для получения обратных вызовов обратных нажатий. Обратный вызов принимает логический параметр, который сообщает, обрабатывается ли обратное нажатие или нет, и лямбда, которая вызывается, когда обрабатывается обратное нажатие. Вот простой пример того, как его создать.
object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { Log.d("TAG", "OnBackPressed") } }
В compose у нас есть аналогичная функция BackHandler. По сути, это компонуемый объект, который принимает лямбду, которая вызывается при обработке обратного нажатия. Компонуемый BackHandler использует OnBackPressedCallback для внутреннего использования. Он добавляет и удаляет обратный вызов, когда компонуемый добавляется и удаляется из композиции соответственно. Здесь вы можете увидеть, как его использовать.
BackHandler(true) { Log.d("TAG", "OnBackPressed") }
Обратите внимание, что из-за того, что функция использует OnBackPressedCallback внутри, она будет блокировать и потреблять предстоящие обратные нажатия. Таким образом, если владелец жизненного цикла использует свой собственный OnBackPressedCallback, он не будет вызываться.
Теперь давайте посмотрим, как обрабатывать OnBackInvokedCallback в compose.
Напомним, что OnBackInvokedCallback
используется для прогнозирующего жеста назад. Он сообщает ОС, что приложение обработало жест «назад», и ОС не должна показывать подсказку о жесте «назад». Прежде чем идти дальше, давайте включим обратный вызов в приложении. Для этого нам нужно добавить следующую строку в файл манифеста.
android:enableOnBackInvokedCallback="true"
Не забудьте включить интеллектуальные жесты назад на устройстве Android 13 или более поздней версии. В противном случае обратный вызов не будет вызван.
К сожалению, нет прямого способа использовать обратный вызов в compose. Но я написал простой компонуемый, который использует OnBackInvokedCallback
внутри и вызывает OnBackInvokedCallback при обработке обратного нажатия. Так же, как BackHandler. Вот код.
@Composable @RequiresApi(Build.VERSION_CODES.TIRAMISU) fun BackInvokeHandler( handleBackHandler: Boolean, priority : Int = OnBackInvokedDispatcher.PRIORITY_DEFAULT, callback : () -> Unit = {} ) { val backInvokedCallback = remember { OnBackInvokedCallback { callback() } } val activity = when(LocalLifecycleOwner.current) { is MainActivity -> LocalLifecycleOwner.current as MainActivity is Fragment -> (LocalLifecycleOwner.current as Fragment).requireActivity() as MainActivity else -> { val context = LocalContext.current if (context is MainActivity) { context } else { throw IllegalStateException("LocalLifecycleOwner is not MainActivity or Fragment") } } } if (handleBackHandler) { activity.onBackInvokedDispatcher.registerOnBackInvokedCallback(priority, backInvokedCallback) } LaunchedEffect(handleBackHandler) { if (!handleBackHandler) { activity.onBackInvokedDispatcher.unregisterOnBackInvokedCallback(backInvokedCallback) } } DisposableEffect(activity.lifecycle, activity.onBackInvokedDispatcher) { onDispose { activity.onBackInvokedDispatcher.unregisterOnBackInvokedCallback(backInvokedCallback) } } }
Как вы могли заметить, для компоновки требуется Android 13 или выше. Это просто, потому что OnBackInvokedCallback доступен только в Android 13 или выше. И я должен добавить, что обратный вызов заблокирует предстоящие обратные свайпы. Итак, если владелец жизненного цикла использует свой собственный OnBackInvokedCallback
, то он не будет вызываться. Более того, если вы используете компонуемый BackHandler и BackInvokedHandler, ОС Android будет использовать компонуемый BackInvokedHandler и игнорировать компонуемый BackHandler. Или, другими словами, когда они оба включены, ОС Android предпочитает компонуемый BackInvokedHandler.
В общем, я надеюсь, что эта статья была полезной. Если у вас есть какие-либо вопросы или предложения, пожалуйста, дайте мне знать в комментариях. Я также создал репозиторий GitHub по этой теме с небольшим полем выбора приложения. Вы можете найти его ниже. Спасибо за чтение. Увидимся в следующей статье.
Не забудьте подписаться на меня для будущих блогов / статей.
Всех вас люблю.
Будьте в курсе новых блогов.
Будьте осторожны.