[Разработка мобильных приложений, Разработка под Android] Навигация в многомодульном приложении на Jetpack без магии и DI
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Когда вы начинаете создавать приложение, в котором хотя бы несколько экранов, всегда встает вопрос - как лучше реализовать навигацию. Вопрос становится интереснее и сложнее, когда вы собираетесь делать многомодульное приложение. Примерно полтора года назад я рассказывал как можно реализовать навигацию c помощью Jetpack в многомодульном проекте. И вот спустя время, я наткнулся на свою реализацию и понял, что можно на том же Jetpack летать по модулям проще: без магии и DI.Архитектура проектаЧтобы покрыть основные кейсы я покажу как реализовать навигацию на многомодульном проекте такой структуры:
Типичная архитектура Android проекта: feature-модули c реализацией экранов зависят от shared-модулей с общей логикой. И app модуль, который зависит от feature и shared.Сейчас довольно популярен подход Single Activity, поэтому в моем примере будет всего одна Activity с глобальным хостом, в котором будут переключаться фрагменты
ПодготовкаОт модуля shared:navigation зависят почти все модули проекта не просто так. В этом модуле реализована функция расширения фрагмента для реализации переходов.
fun Fragment.navigate(actionId: Int, hostId: Int? = null, data: Serializable? = null) {
val navController = if (hostId == null) {
findNavController()
} else {
Navigation.findNavController(requireActivity(), hostId)
}
val bundle = Bundle().apply { putSerializable("navigation data", data) }
navController.navigate(actionId, bundle)
}
У функции есть параметры:
- actionId - id действия графа навигации
- hostId - id хоста графа навигации. Если не будет передан, то будет использован текущий хост
- data - объект с данными типа Serializable
В этом же модуле реализована функция расширения фрагмента для получения данных, которые были переданы при выполнении действия навигации.
val Fragment.navigationData: Serializable?
get() = arguments?.getSerializable("navigation data")
Также в этом модуле надо описать id хостов навигации, чтобы к ним был доступ из feature модулей. Для этого в директории ресурсов надо создать файл res/value/ids.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="host_global" type="id"/>
<item name="host_main" type="id"/>
</resources>
Отлично! Подготовка завершена, можно приступать к самой реализации навигации.Простые переходы в feature-модуляхСэмулируем типичное поведение экрана splash. Обычно с этого экрана идет переход либо к онбордингу, либо к главному экрану приложения, либо к экрану авторизации. Реализуем нечто похожее: пусть фрагмент фичи splash будет уметь переходить на экран онбординга и на главный экран по нажатию кнопки.Для начала создади id для этих действий: запишем их в res/value/ids.xml модуля splash
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="action_splashFragment_to_mainFragment" type="id"/>
<item name="action_splashFragment_to_onboardingFragment" type="id"/>
</resources>
Id для действий переходов я рекомендую создавать именно в модулях фич, которые будут использовать эти действия, а не в модуле shared:navigation. Это позволяет модулю знать только о необходимых действиях.Теперь можно использовать созданные id для выполнения переходов.
import com.example.smmn.shared.navigation.navigate
class SplashFragment : Fragment(R.layout.fragment_splash) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
buttonToOnboarding.setOnClickListener {
navigate(R.id.action_splashFragment_to_onboardingFragment)
}
buttonToMain.setOnClickListener {
navigate(R.id.action_splashFragment_to_mainFragment)
}
}
}
Обратите внимание, что для выполнения перехода используется функция расширения из модуля shared:navigation.Но чтобы этот переход заработал надо настроить глобальный хост и реализовать глобальную навигацию.Глобальный хостВ нашей архитектуре всего одна Activity. Она будет содержать глобальный хост для фрагментов. Для этого нам ничего не потребуется реализовывать в самом коде Activity.
class MainActivity : AppCompatActivity(R.layout.activity_main)
Хост добавить надо в ее разметке activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@id/host_global"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_global"
tools:ignore="FragmentTagUsage" />
Глобальная навигацияЭто навигация, которая происходит в глобальном хосте. Для ее реализации надо реализовать в модуле app граф навигации res/navigation/navigation_global.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_global"
app:startDestination="@id/splashFragment">
<fragment
android:id="@+id/splashFragment"
android:name="com.example.smmn.feature.splash.SplashFragment"
android:label="SplashFragment">
<action
android:id="@id/action_splashFragment_to_mainFragment"
app:destination="@id/mainFragment"
app:popUpTo="@id/navigation_global" />
<action
android:id="@id/action_splashFragment_to_onboardingFragment"
app:destination="@id/onboardingFragment"
app:popUpTo="@id/navigation_global" />
</fragment>
<fragment
android:id="@+id/mainFragment"
android:name="com.example.smmn.feature.main.MainFragment"
android:label="MainFragment" >
<action
android:id="@id/action_mainFragment_to_splashFragment"
app:popUpTo="@id/navigation_global"
app:destination="@id/splashFragment" />
</fragment>
<fragment
android:id="@+id/onboardingFragment"
android:name="com.example.smmn.feature.onboarding.OnboardingFragment"
android:label="OnboardingFragment">
<action
android:id="@id/action_onboardingFragment_to_mainFragment"
app:destination="@id/mainFragment"
app:popUpTo="@id/navigation_global" />
</fragment>
</navigation>
Обратите внимание, что у каждого фрагмента есть набор action (действий) с помощью которых происходит переход между фрагментами. В действии указывается на какой фрагмент будет выполнен переход и как обрабатывать переход назад, например, при нажатии кнопки "Back".И очень важно отметить, что id действий прописаны без знака +, то есть мы не создаем id в этом графе, а используем id, прописанные в feature модуле.Прописанные id в модуле splash
<item name="action_splashFragment_to_mainFragment" type="id"/>
<item name="action_splashFragment_to_onboardingFragment" type="id"/>
Использование их в действиях глобального графа
<action
android:id="@id/action_splashFragment_to_mainFragment"
app:destination="@id/mainFragment"
app:popUpTo="@id/navigation_global" />
<action
android:id="@id/action_splashFragment_to_onboardingFragment"
app:destination="@id/onboardingFragment"
app:popUpTo="@id/navigation_global" />
Вложенный хостВ Jetpack навигации есть возможность использовать вложенный хост. Это очень полезно, когда мы хотим сделать меню типа BottomNavigation и использовать для этого меню отдельный граф навигации.В нашем примере во вложенном хосте будут фичи профиля и настроек.
Благодаря библиотеке navigation-ui, реализовать вложенную навигацию довольно просто.В модуле main создадим меню для BottomNavigation в res/menu/menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/profileFragment"
android:icon="@drawable/ic_baseline_account_circle_24"
android:title="@string/main_menu_title_profile" />
<item
android:id="@+id/settingsFragment"
android:icon="@drawable/ic_baseline_settings_24"
android:title="@string/main_menu_title_settings" />
</menu>
Создадим граф навигации в res/navigation/navigation_main.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_main"
app:startDestination="@id/profileFragment">
<fragment
android:id="@+id/profileFragment"
android:name="com.example.smmn.feature.profile.ProfileFragment"
android:label="ProfileFragment">
<action
android:id="@id/action_profileFragment_to_infoFragment"
app:destination="@id/infoFragment" />
</fragment>
<fragment
android:id="@+id/settingsFragment"
android:name="com.example.smmn.feature.settings.SettingsFragment"
android:label="SettingsFragment" />
<fragment
android:id="@+id/infoFragment"
android:name="com.example.smmn.feature.info.InfoFragment"
android:label="InfoFragment" />
</navigation>
Здесь важно указать у фрагментов те же id что указаны в файле меню res/menu/menu_main.xml. И не забывать, что id действий брать из модулей фич.Осталось добавить хост и меню в разметку фрагмента res/layout/fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@id/host_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation_main" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
app:elevation="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/menu_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
И в самом фрагменте настроить bottomNavigationView
class MainFragment : Fragment(R.layout.fragment_main) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
NavigationUI.setupWithNavController(
bottomNavigationView,
Navigation.findNavController(requireActivity(), R.id.host_main)
)
}
}
Переходы между фрагментами из разных хостовДовольно частый случай, когда надо перейти с экрана, который находится внутри вложенного хоста, на экран глобального хоста. Например, у нас есть главный экран c хостом для экранов главных фич: настроек и профиля.
И на экране настроек, который находится внутри хоста главного экрана (не глобальный хост, а глубже) надо выполнить переход на экран сплэша, который находится в глобальном хосте. Например это может понадобиться, если надо разлогинить текущего пользователя.В этом случае также воспользуемся функцией расширения фрагмента, но укажем id глобального хоста. Мы имеем к нему доступ из фичи, так как он прописан в модуле shared:navigation.
class SettingsFragment : Fragment(R.layout.fragment_settings) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
buttonToSplash.setOnClickListener {
navigate(R.id.action_mainFragment_to_splashFragment, R.id.host_global)
}
}
}
Id действия по аналогии с предыдущим переходом прописан в самом модуле фичи res/values/ids.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="action_mainFragment_to_splashFragment" type="id"/>
</resources>
Переходы между фрагментами с передачей и получением данныхЧтобы выполнить переход с передачей данных необходимо, чтобы данные можно было положить в bundle. Это могуг быть какие-то примитивные типы или объекты Serializable классов.Выше я уже реализовал функцию расширения фрагмента для выполнения перехода, в которую можно передать объект Serializable класса. Аналогично вы можете реализовать передачу примитивных типов.Чтобы передать объект Serializable класса надо чтобы модуль фичи, с которой происходит переход, и модуль фичи, на которую происходит переход, имели доступ к модулю с таким классом. В нашем случае создадим модуль shared:model где будет лежать Serializable класс Info.
data class Info(
val name: String,
val surname: String
) : Serializable
Переход будет происходить с экрана profile на экран info. Создадим объект Info и передадим его в функцию расширения фрагмента.
class ProfileFragment : Fragment(R.layout.fragment_profile) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
buttonToInfo.setOnClickListener {
navigate(R.id.action_profileFragment_to_infoFragment, data = Info("name", "surname"))
}
}
}
И получим данные используя другую функцию расширения фрагмента, созданную ранее.
class InfoFragment : Fragment(R.layout.fragment_info) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val info = navigationData as? Info ?: return
textView.text = info.toString()
}
}
Так это будет выглядеть в приложении
Заметьте, что мы не указывали в каком хосте выполнить переход, и переход произошел в текущем хосте.ЗаключениеТаким несложным способом можно организовать навигацию в вашем многомодульном проекте, используя Jetpack и пару функций расширения. Этот подход функционально не отличается от подхода, который я описывал ранее, но в использовании он намного проще и лаконичнее.Оставляю ссылку на код примера приложения.Буду рад обратной связи!
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка мобильных приложений, Монетизация мобильных приложений, Медийная реклама, Управление продуктом, IT-компании] Facebook всё-таки изменит свои рекламные инструменты из-за новых правил Apple о приватности
- [Разработка мобильных приложений, Разработка под e-commerce, Карьера в IT-индустрии, IT-компании] «Кадровый голод» или почему IT-компании находятся в постоянном поиске сотрудников
- [Программирование, Проектирование и рефакторинг, Разработка под Android, Kotlin] Пишем под android с Elmslie
- [Разработка под iOS, Разработка мобильных приложений, Разработка под Android] В ВТБ Онлайн появилась темная тема
- [Разработка веб-сайтов, Разработка мобильных приложений, Развитие стартапа, Дизайн, Удалённая работа] Иной подход к коммуникации удаленных команд
- [Разработка мобильных приложений, Разработка под Android, Тестирование мобильных приложений] Давайте будем прямыми в своих intent (перевод)
- [IT-инфраструктура, API, Облачные сервисы, Kubernetes] Масштабирование Kubernetes в Pinterest: через сбои и аварии (перевод)
- [Разработка мобильных приложений, Искусственный интеллект, Интернет вещей] Русские программисты не сдаются
- [Спортивное программирование, Разработка мобильных приложений, Машинное обучение, Дизайн] Открываем регистрацию на седьмой сезон VK Cup
- [Разработка мобильных приложений, Законодательство в IT, IT-компании] Минцифры рассказало о приложении «ГосДоки»
Теги для поиска: #_razrabotka_mobilnyh_prilozhenij (Разработка мобильных приложений), #_razrabotka_pod_android (Разработка под Android), #_android, #_jetpack, #_navigation, #_graph, #_hosts, #_action, #_androidx, #_razrabotka_mobilnyh_prilozhenij (
Разработка мобильных приложений
), #_razrabotka_pod_android (
Разработка под Android
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 21:18
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Когда вы начинаете создавать приложение, в котором хотя бы несколько экранов, всегда встает вопрос - как лучше реализовать навигацию. Вопрос становится интереснее и сложнее, когда вы собираетесь делать многомодульное приложение. Примерно полтора года назад я рассказывал как можно реализовать навигацию c помощью Jetpack в многомодульном проекте. И вот спустя время, я наткнулся на свою реализацию и понял, что можно на том же Jetpack летать по модулям проще: без магии и DI.Архитектура проектаЧтобы покрыть основные кейсы я покажу как реализовать навигацию на многомодульном проекте такой структуры: Типичная архитектура Android проекта: feature-модули c реализацией экранов зависят от shared-модулей с общей логикой. И app модуль, который зависит от feature и shared.Сейчас довольно популярен подход Single Activity, поэтому в моем примере будет всего одна Activity с глобальным хостом, в котором будут переключаться фрагменты ПодготовкаОт модуля shared:navigation зависят почти все модули проекта не просто так. В этом модуле реализована функция расширения фрагмента для реализации переходов. fun Fragment.navigate(actionId: Int, hostId: Int? = null, data: Serializable? = null) {
val navController = if (hostId == null) { findNavController() } else { Navigation.findNavController(requireActivity(), hostId) } val bundle = Bundle().apply { putSerializable("navigation data", data) } navController.navigate(actionId, bundle) }
val Fragment.navigationData: Serializable?
get() = arguments?.getSerializable("navigation data") <?xml version="1.0" encoding="utf-8"?>
<resources> <item name="host_global" type="id"/> <item name="host_main" type="id"/> </resources> <?xml version="1.0" encoding="utf-8"?>
<resources> <item name="action_splashFragment_to_mainFragment" type="id"/> <item name="action_splashFragment_to_onboardingFragment" type="id"/> </resources> import com.example.smmn.shared.navigation.navigate
class SplashFragment : Fragment(R.layout.fragment_splash) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) buttonToOnboarding.setOnClickListener { navigate(R.id.action_splashFragment_to_onboardingFragment) } buttonToMain.setOnClickListener { navigate(R.id.action_splashFragment_to_mainFragment) } } } class MainActivity : AppCompatActivity(R.layout.activity_main)
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@id/host_global" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/navigation_global" tools:ignore="FragmentTagUsage" /> <?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation_global" app:startDestination="@id/splashFragment"> <fragment android:id="@+id/splashFragment" android:name="com.example.smmn.feature.splash.SplashFragment" android:label="SplashFragment"> <action android:id="@id/action_splashFragment_to_mainFragment" app:destination="@id/mainFragment" app:popUpTo="@id/navigation_global" /> <action android:id="@id/action_splashFragment_to_onboardingFragment" app:destination="@id/onboardingFragment" app:popUpTo="@id/navigation_global" /> </fragment> <fragment android:id="@+id/mainFragment" android:name="com.example.smmn.feature.main.MainFragment" android:label="MainFragment" > <action android:id="@id/action_mainFragment_to_splashFragment" app:popUpTo="@id/navigation_global" app:destination="@id/splashFragment" /> </fragment> <fragment android:id="@+id/onboardingFragment" android:name="com.example.smmn.feature.onboarding.OnboardingFragment" android:label="OnboardingFragment"> <action android:id="@id/action_onboardingFragment_to_mainFragment" app:destination="@id/mainFragment" app:popUpTo="@id/navigation_global" /> </fragment> </navigation> <item name="action_splashFragment_to_mainFragment" type="id"/>
<item name="action_splashFragment_to_onboardingFragment" type="id"/> <action
android:id="@id/action_splashFragment_to_mainFragment" app:destination="@id/mainFragment" app:popUpTo="@id/navigation_global" /> <action android:id="@id/action_splashFragment_to_onboardingFragment" app:destination="@id/onboardingFragment" app:popUpTo="@id/navigation_global" /> Благодаря библиотеке navigation-ui, реализовать вложенную навигацию довольно просто.В модуле main создадим меню для BottomNavigation в res/menu/menu_main.xml <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/profileFragment" android:icon="@drawable/ic_baseline_account_circle_24" android:title="@string/main_menu_title_profile" /> <item android:id="@+id/settingsFragment" android:icon="@drawable/ic_baseline_settings_24" android:title="@string/main_menu_title_settings" /> </menu> <?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation_main" app:startDestination="@id/profileFragment"> <fragment android:id="@+id/profileFragment" android:name="com.example.smmn.feature.profile.ProfileFragment" android:label="ProfileFragment"> <action android:id="@id/action_profileFragment_to_infoFragment" app:destination="@id/infoFragment" /> </fragment> <fragment android:id="@+id/settingsFragment" android:name="com.example.smmn.feature.settings.SettingsFragment" android:label="SettingsFragment" /> <fragment android:id="@+id/infoFragment" android:name="com.example.smmn.feature.info.InfoFragment" android:label="InfoFragment" /> </navigation> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@id/host_main" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="0dp" app:defaultNavHost="true" app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/navigation_main" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNavigationView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" app:elevation="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/menu_main" /> </androidx.constraintlayout.widget.ConstraintLayout> class MainFragment : Fragment(R.layout.fragment_main) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) NavigationUI.setupWithNavController( bottomNavigationView, Navigation.findNavController(requireActivity(), R.id.host_main) ) } } И на экране настроек, который находится внутри хоста главного экрана (не глобальный хост, а глубже) надо выполнить переход на экран сплэша, который находится в глобальном хосте. Например это может понадобиться, если надо разлогинить текущего пользователя.В этом случае также воспользуемся функцией расширения фрагмента, но укажем id глобального хоста. Мы имеем к нему доступ из фичи, так как он прописан в модуле shared:navigation. class SettingsFragment : Fragment(R.layout.fragment_settings) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) buttonToSplash.setOnClickListener { navigate(R.id.action_mainFragment_to_splashFragment, R.id.host_global) } } } <?xml version="1.0" encoding="utf-8"?>
<resources> <item name="action_mainFragment_to_splashFragment" type="id"/> </resources> data class Info(
val name: String, val surname: String ) : Serializable class ProfileFragment : Fragment(R.layout.fragment_profile) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) buttonToInfo.setOnClickListener { navigate(R.id.action_profileFragment_to_infoFragment, data = Info("name", "surname")) } } } class InfoFragment : Fragment(R.layout.fragment_info) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val info = navigationData as? Info ?: return textView.text = info.toString() } } Заметьте, что мы не указывали в каком хосте выполнить переход, и переход произошел в текущем хосте.ЗаключениеТаким несложным способом можно организовать навигацию в вашем многомодульном проекте, используя Jetpack и пару функций расширения. Этот подход функционально не отличается от подхода, который я описывал ранее, но в использовании он намного проще и лаконичнее.Оставляю ссылку на код примера приложения.Буду рад обратной связи! =========== Источник: habr.com =========== Похожие новости:
Разработка мобильных приложений ), #_razrabotka_pod_android ( Разработка под Android ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 21:18
Часовой пояс: UTC + 5