Урок 12. Навигация в приложении. Начало работы с Navigation Architecture Component

В этом уроке на практике познакомимся с библиотекой 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 представляет собой новый тип ресурса , который определяет все возможные пути, доступные пользователю в приложении. Он показывает визуально все пункты назначения, которые могут быть достигнуты из данного пункта назначения. Редактор навигации Android Studio отображает Navigation Graph наглядно.

Редактор навигации

  1. Откройтеres/navigation/mobile_navigation.xml
  2. Перейдите в режим «Дизайн»:Navigation Graph

Navigation Graph показывает доступные пункты назначения. Стрелки между пунктами назначения называются actions (действия). Больше мы поговорим о них позже.

  1. Нажмите на пункт назначения, чтобы увидеть его атрибуты.
  2. Нажмите на любое действие, представленное стрелкой, чтобы увидеть его атрибуты.

Нажмите на пункт назначения, чтобы увидеть его атрибуты

Анатомия навигационного 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 в загруженном вами коде.

Вы должны сравнить код, который вы пишете, с включенным закомментированным кодом.

  1. Откройте res/navigation/mobile_navigation.xmlи выберите вкладку « Дизайн».
  2. Нажмите значок « Новый пункт назначения»и выберите «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, который управляет фрагментами в 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):

  1. Открыть HomeFragment.kt
  2. подключить 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)
}

 

  1. Запустите приложение и нажмите кнопку « Перейти кместу назначения». Обратите внимание, что кнопка перемещается к 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.

Урок 13. Навигация в Android приложении. Интеграция в новый проект, добавление пунктов назначения (destinations) и переходов между ними (actions)

Коментарі: 1
  1. gorich

    Здравствуйте, возникает ошибка при скачивании стартового проекта по ссылке. Пожалуйста обновите ее

Додати коментар