[Разработка мобильных приложений, Разработка под Android] Navigation Component и multi backstack navigation
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Вы сейчас в четвертой части большого материала про Navigation Component в многомодульном проекте. Если вы уже знаете:
- Что такое Navigation Component
- Как работает плагин Safe Args и что он делает
- Как можно построить работу с Navigation Component в многомодульном проекте
То добро пожаловать в заключительную часть истории о моем опыте с этой прекрасной библиотекой — про решение для iOS-like multistack-навигации.Если не знаете, то выйдите и зайдите нормально прочитайте сначала три статьи выше.В дополнение к библиотеке Navigation Component Google выпустили несколько интерфейсных дополнений под названием NavigationUI, которые помогут вам подключить навигацию к BottomBar, Menu и прочим стандартным компонентам. Но часто поступают требования, чтобы на каждой вкладке был свой стек и текущие состояния сохранялись при переходе между ними. К сожалению, из коробки Navigation Component и NavigationUI так не умеют.Поддержку такого подхода представили сами Google в своем architecture-components-samples репозитории на GitHub (https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample). Суть его проста:
- Добавляем FragmentContainer.
- Создаем NavHostFragment и граф под каждую вкладку.
- При выборе вкладки присоединяем необходимый NavHostFragment и отсоединяем текущий с помощью транзакций FragmentManager-a.
Но в ходе работы с этим решением я переделал некоторые моменты, связанные со спецификой проекта:
- Многие приложения имеют sign in / up flow, on boarding и прочие экраны, которые не должны входить в стеки, но даже в таком случае все достаточно просто оборачивается стандартными средствами. Навигацию между этими частями можно выстроить уже как обычно, например, как в предыдущей части.
- В примере все стеки инициализируются сразу при старте приложения. Связано это с корректной работой NavigationBottomBar и обработкой Deep Link-ов. Но я часто сталкивался с проектами, где deep link-и не нужны и бар навигации требует кастомизации. Проект, на котором я обкатывал подход — не исключение. Глядя на оригинальный файл NavigationExtensions в 250 loc, я решил выбросить все ненужное и сделать lazy-инициализацию NavHost-ов, оставив только основные функции:
Функция поиска / инициализации требуемого NavHost-фрагмента:
fun obtainNavHostFragment(
fragmentManager: FragmentManager,
fragmentTag: String,
navGraphId: Int,
containerId: Int
): NavHostFragment {
// If the Nav Host fragment exists, return it
val existingFragment =
fragmentManager.findFragmentByTag(fragmentTag) as NavHostFragment?
existingFragment?.let { return it }
// Otherwise, create it and return it.
val navHostFragment = NavHostFragment.create(navGraphId)
fragmentManager.beginTransaction()
.add(containerId, navHostFragment, fragmentTag)
.commitNow()
return navHostFragment
}
Функция смены NavHost-ов:
protected fun selectTab(tab: Tab) {
val newFragment = obtainNavHostFragment(
childFragmentManager,
getFragmentTag(tabs.indexOf(tab)),
tab.graphId,
containerId
)
val fTrans = childFragmentManager.beginTransaction()
with(fTrans) {
if (selectedFragment != null) detach(selectedFragment!!)
attach(newFragment)
commitNow()
}
selectedFragment = newFragment
currentNavController = selectedFragment!!.navController
tabSelected(tab)
}
Функция своей обработки нажатия на кнопку “Back”:
activity?.onBackPressedDispatcher?.addCallback(
viewLifecycleOwner,
object: OnBackPressedCallback(true){
override fun handleOnBackPressed() {
val isNavigatedUp = currentNavController.navigateUp()
if(isNavigatedUp){
return
}else{
activity?.finish()
}
}
}
)
В итогеТаким образом мы получаем iOS-like навигацию и даже лучше, так как имеем lazy-нагрузку на стеках и меньшее количество кода. Приятный бонус — мы имеем полностью очевидную и прозрачную схему навигации, которую просто масштабировать и модифицировать.
===========
Источник:
habr.com
===========
Похожие новости:
- [Тестирование IT-систем, Разработка под Android] Тестирование From Zero to Hero. Часть 1
- [Программирование, Разработка мобильных приложений, Конференции, Flutter] Анонс вебинара «Почему компании всё чаще выбирают Flutter и что это значит для разработчиков»
- [Разработка под Android, Google API, Тестирование мобильных приложений, Аналитика мобильных приложений] Приложение отвечает: как мы уменьшили количество ANR-ошибок в шесть раз. Часть 1, про сбор данных (перевод)
- [Программирование, Разработка мобильных приложений, Dart, Flutter] Работа с асинхронностью в Dart
- [Разработка под iOS, Разработка мобильных приложений, Администрирование баз данных, Swift] Быстрый, простой, сложный: как мы выпилили Realm
- [Разработка мобильных приложений, Разработка под Android, Flutter] Все, что вам нужно знать о переходе с Flutter страницы (перевод)
- [Работа с видео, Разработка под Android, Софт] Видеоплеер заблокировали в Google Play за поддержку субтитров ASS
- [Разработка мобильных приложений, Законодательство в IT, Социальные сети и сообщества] Индия сделает запрет 59 китайских приложений постоянным
- [Python, Разработка мобильных приложений, Интерфейсы, Промышленное программирование] Открываем четыре Школы: разработки интерфейсов, бэкенда, мобильной разработки и дизайна
- [Разработка под Android, Производство и разработка электроники, Процессоры, Интернет вещей] Компания T-Head собрала порт Android 10 для процессоров архитектуры RISC-V
Теги для поиска: #_razrabotka_mobilnyh_prilozhenij (Разработка мобильных приложений), #_razrabotka_pod_android (Разработка под Android), #_android, #_navigation_component, #_navigation_menu, #_backstack, #_razrabotka_mobilnyh_prilozhenij (
Разработка мобильных приложений
), #_razrabotka_pod_android (
Разработка под Android
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 21:05
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Вы сейчас в четвертой части большого материала про Navigation Component в многомодульном проекте. Если вы уже знаете:
fun obtainNavHostFragment(
fragmentManager: FragmentManager, fragmentTag: String, navGraphId: Int, containerId: Int ): NavHostFragment { // If the Nav Host fragment exists, return it val existingFragment = fragmentManager.findFragmentByTag(fragmentTag) as NavHostFragment? existingFragment?.let { return it } // Otherwise, create it and return it. val navHostFragment = NavHostFragment.create(navGraphId) fragmentManager.beginTransaction() .add(containerId, navHostFragment, fragmentTag) .commitNow() return navHostFragment } protected fun selectTab(tab: Tab) {
val newFragment = obtainNavHostFragment( childFragmentManager, getFragmentTag(tabs.indexOf(tab)), tab.graphId, containerId ) val fTrans = childFragmentManager.beginTransaction() with(fTrans) { if (selectedFragment != null) detach(selectedFragment!!) attach(newFragment) commitNow() } selectedFragment = newFragment currentNavController = selectedFragment!!.navController tabSelected(tab) } activity?.onBackPressedDispatcher?.addCallback(
viewLifecycleOwner, object: OnBackPressedCallback(true){ override fun handleOnBackPressed() { val isNavigatedUp = currentNavController.navigateUp() if(isNavigatedUp){ return }else{ activity?.finish() } } } ) =========== Источник: habr.com =========== Похожие новости:
Разработка мобильных приложений ), #_razrabotka_pod_android ( Разработка под Android ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 21:05
Часовой пояс: UTC + 5