В этом уроке на практике познакомимся с библиотекой Navigation Architecture Component , которая позволяет пользователям перемещаться между различными частями контента в вашем приложении. Компонент навигации входит в набор компонентов Android Jetpack и помогает реализовать навигацию, от простых нажатий кнопок до более сложных шаблонов, таких как панели приложений (appbars) и панель навигации (navigation drawer). Компонент навигации также обеспечивает согласованное и предсказуемое взаимодействие с пользователем, придерживаясь установленного набора принципов, о которых мы говорили на прошлом уроке.
Введение
Navigation Architecture Component упрощает осуществление навигации, а также помогает визуализировать navigation flow вашего приложения. Библиотека предоставляет ряд преимуществ, в том числе:
- Автоматическая обработка транзакций фрагментов
- Корректная обработка кнопок «Вверх» и «Назад» по умолчанию
- Поведение по умолчанию для анимации и переходов
- Deep linking как first class operation
- Реализация шаблонов навигации пользовательского интерфейса (таких как navigation drawer и bottom navigation) с небольшой дополнительной работой
- Безопасность типов при передаче информации во время навигации
- Инструменты Android Studio для визуализации и редактирования navigation flow приложения
В этом уроке нам понадобится среда разработки Android Studio версии 3.3 или выше.
Мы будем использовать готовый проект, в котором уже есть необходимые активити или фрагменты. Нам нужно настроить навигацию в приложении, используя Navigation Architecture Component.
Скачайте стартовый проект по ссылке
Обзор компонента навигации
Компонент навигации состоит из трех ключевых частей:
- Navigation graph: ресурс XML, который содержит всю связанную с навигацией информацию в одном централизованном месте. Это включает в себя все отдельные области содержимого в вашем приложении, называемые destinations (пункты назначения), а также возможные пути, которые пользователь может пройти через ваше приложение.
- NavHost: Пустой контейнер, который отображает пункты назначения из вашего графика навигации. Компонент Navigation содержит реализацию NavHost по умолчанию – NavHostFragment, которая отображает фрагменты – места назначения.
- NavController: Объект, который управляет навигацией приложения в NavHost. NavController управляет перемещениями контента мест назначения в NavHost , в процессе перемещения пользователей по приложению.
Мы используем объект NavController, сообщая ему путь в ресурсе Navigation Graph. Затем объекту NavController будет показан соответствующий пункт назначения в NavHostFragment.
Давайте посмотрим, как это выглядит на практике, начиная с нового ресурса Navigation Graph.
Destinations
Компонент навигации представляет концепцию Destinations – пункта назначения . Пункт назначения – это любое место, в котором вы можете перемещаться в приложении, обычно это фрагмент или активити. Они поддерживаются “из коробки”, но вы также можете создавать свои собственные типы назначения, если это необходимо.
Navigation Graph
Navigation Graph представляет собой новый тип ресурса , который определяет все возможные пути, доступные пользователю в приложении. Он показывает визуально все пункты назначения, которые могут быть достигнуты из данного пункта назначения. Редактор навигации Android Studio отображает Navigation Graph наглядно.
Редактор навигации
- Откройтеres/navigation/mobile_navigation.xml
- Перейдите в режим «Дизайн»:
Navigation Graph показывает доступные пункты назначения. Стрелки между пунктами назначения называются actions (действия). Больше мы поговорим о них позже.
- Нажмите на пункт назначения, чтобы увидеть его атрибуты.
- Нажмите на любое действие, представленное стрелкой, чтобы увидеть его атрибуты.
Анатомия навигационного XML-файла
Все изменения, которые вы делаете в графическом редакторе навигации, изменяют базовый XML-файл, подобно тому, как редактор макетов изменяет XML-макет.
Перейдите на вкладку « Текст »:
Вы увидите такой XML-код:
<navigation 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" app:startDestination="@+id/home_dest"> <!-- ...tags for fragments and activities here --> </navigation>
Примечание:
- <navigation> является корневым узлом каждого навигационного графа.
- <navigation>содержит один или несколько пунктов назначения, представленных элементами <activity>или <fragment>.
- app:startDestination является атрибутом, который указывает место назначения, которое запускается по умолчанию, когда пользователь впервые открывает приложение.
Давайте посмотрим на место назначения фрагмента:
<fragment android:id="@+id/flow_step_one_dest" android:name="com.example.android.codelabs.navigation.FlowStepFragment" tools:layout="@layout/flow_step_one_fragment"> <argument .../> <action android:id="@+id/next_action" app:destination="@+id/flow_step_two_dest"> </action> </fragment>
Примечание:
- android:id определяет идентификатор для фрагмента, который вы можете использовать для ссылки на место назначения в другом месте этого XML и вашего кода.
- android:name объявляет полное имя класса фрагмента для создания экземпляра при переходе к этому месту назначения.
- tools:layout указывает, какой макет должен отображаться в графическом редакторе.
Некоторые теги <fragment> также содержат <action>, <argument>,и <deepLink>, все это мы рассмотрим позже.
Пример приложения уже содержит несколько пунктов назначения на графике. Давайте мы добавим новое назначение.
Примечание . Код для каждого шага в этой кодовой метке включен, закомментирован между операторами TODO в загруженном вами коде.
Вы должны сравнить код, который вы пишете, с включенным закомментированным кодом.
- Откройте res/navigation/mobile_navigation.xmlи выберите вкладку « Дизайн».
- Нажмите значок « Новый пункт назначения»и выберите «settings_fragment»
Результатом является новое назначение, которое отображает предварительный просмотр макета фрагмента в окне конструктора.
Обратите внимание, что вы также можете редактировать XML-файл напрямую, чтобы добавить места назначения: mobile_navigation.xml
<fragment android:id="@+id/settings_dest" android:name="com.example.android.codelabs.navigation.SettingsFragment" android:label="@string/settings" tools:layout="@layout/settings_fragment" />
Чтобы следовать нашему соглашению об именах, измените идентификатор settings_dest на значение по умолчанию settingsFragment.
Активити и навигация
Компонент «Навигация» следует указаниям, изложенным в « Принципах навигации» . Принципы навигации рекомендуют использовать Активити в качестве точек входа для вашего приложения. Активити также будут содержать глобальную навигацию, такую как bottom nav (нижняя панель навигации). А для конкретного места назначения мы будем использовать фрагменты.
Чтобы все это заработало, вам нужно изменить макет активити, чтобы он содержал специальный виджет – NavHostFragment, управляющий перемещением в destinations – точки назначения. Простой макет с поддержкой навигации выглядит следующим образом:
Пример этого кода можно найти в res/layout-470dp/navigation_activity.xml:
<LinearLayout .../> <androidx.appcompat.widget.Toolbar .../> <fragment android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:id="@+id/my_nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="@navigation/mobile_navigation" app:defaultNavHost="true" /> <com.google.android.material.bottomnavigation.BottomNavigationView .../> </LinearLayout>
Примечание:
- Это макет активити. Он содержит глобальную навигацию, включая нижнюю навигационную панель и панель инструментов Toolbar
- android:name=”androidx.navigation.fragment.NavHostFragment”и app:defaultNavHost=”true” подключает системную кнопку «Назад» кNavHostFragment
- app:navGraph=”@navigation/mobile_navigation”связывает NavHostFragment с навигационным графом. Navigation Graph определяет все пункты назначения, к которым пользователь может перемещаться, в этом NavHostFragment.
NavController
Наконец, когда пользователь делает что-то вроде нажатия кнопки, вам нужно запустить команду навигации. Нам поможет специальный класс NavController, который управляет фрагментами в NavHostFragment.
// Command to navigate to flow_step_one_dest findNavController().navigate(R.id.flow_step_one_dest)
Обратите внимание, что вы передаете либо destination , либо action ID для навигации. Это идентификаторы, определенные в графе навигации XML. Это пример передачи destination ID.
NavController мощный инструмент, потому что когда вы вызываете методы типа navigate() или popBackStack(), он переводит эти команды в соответствующие операции фреймворка в зависимости от типа пункта назначения, к которому вы переходите. Например, когда вы вызываете navigate() с места назначения активити, NavController вызывает startActivity() от вашего имени.
Есть несколько способов получить объект NavController, связанный с вашим NavHostFragment. В Kotlin рекомендуется использовать одну из следующих функций расширения в зависимости от того, вызываете ли вы команду навигации из фрагмента, активити или view-компонента:
Ваш NavController ассоциируется с NavHostFragment. Таким образом, какой бы метод вы ни использовали, вы должны быть уверены, что идентификатор фрагмента, активити или view либо собственно NavHostFragment либо имеет NavHostFragment в качестве родителя. В противном случае вы получите IllegalStateException.
Перейдите к месту назначения с помощью NavController
Подключим кнопку Navigate To Destination , чтобы перейти к пункту назначения flow_step_one_dest (который является пунктом назначения FlowStepFragment):
- Открыть HomeFragment.kt
- подключить navigate_destination_button в onViewCreated()
HomeFragment.kt
val button = view.findViewById<Button>(R.id.navigate_destination_button) button?.setOnClickListener { findNavController().navigate(R.id.flow_step_one_dest, null) }
- Запустите приложение и нажмите кнопку « Перейти кместу назначения». Обратите внимание, что кнопка перемещается к flow_step_one_dest.
Вы также можете использовать удобный метод Navigation.createNavigateOnClickListener(@IdRes destId: int, bundle: Bundle). Этот метод создаст OnClickListener для перехода к заданному месту назначения с набором аргументов, которые будут переданы получателю.
Код слушателя кликов будет выглядеть так:
val button = view.findViewById<Button>(R.id.navigate_destination_button) button?.setOnClickListener( Navigation.createNavigateOnClickListener(R.id.flow_step_one_dest, null) )
На этом наш урок подошел к концу. Продолжение в следующем уроке. Вопросы задавайте в комментариях на сайте fandroid.info.
Здравствуйте, возникает ошибка при скачивании стартового проекта по ссылке. Пожалуйста обновите ее