Навигация для Android с использованием Navigation Architecture Component: пошаговое руководство

Попробуем, пользуясь официальным руководством и примерами кода, построить работающую систему навигации для будущего многоэкранного приложения в соответствии со стандартами Navigation Architecture Component. Статья включает следующие разделы:

Часть 1. Подготовительные работы
 — 1.1. Создание проекта
— 1.2. Зависимости (Dependencies)
— 1.3. Страницы: создание фрагментов
— 1.4. Адреса: файл ресурсов типа «Navigation»
— 1.5. Фрейм: виджет NavHostFragment

Часть 2. Элементы навигации
 — 2.1. Навигация с помощью кнопок
— 2.2. Боковое меню (Drawer)
— 2.3. Панель инструментов: Toolbar вместо ActionBar
— 2.4. Нижнее меню (Bottom Navigation)
— 2.5. Всплывающее меню (Overflow Menu)

Краткие выводы и ссылка на github

Часть 1. Подготовительные работы


1.1. Создание проекта


Нам понадобятся базовые знания Котлина, IDE Android Studio версии не ниже 3.3, смартфон или эмулятор с версией API 14 или выше.

Создадим в Android Studio новый проект под названием «Navigation2019».

vrt7k-7w_qqepkjwj7r4trow5i0.png

_qebft82drjjd8kkbd-by5s7mq4.png

IDE создаст файл главной активности «MainActivity.kt» и его макет (шаблон) «activity_main.xml».

nwrgxjkoojesjdh7efew6-dusxm.jpeg

1.2. Зависимости (Dependencies)


Откроем файл «build.gradle» модуля (не проекта, а именно модуля) и в блок «dependencies» добавим необходимые зависимости:

def nav_version = «1.0.0»
implementation «android.arch.navigation:navigation-fragment-ktx:$nav_version»
implementation «android.arch.navigation:navigation-ui-ktx:$nav_version»

sig86zem47m6xonnz0rypaybk1o.jpeg

Мы использовали библиотеки версии 1.0.0, но в будущем ситуация может измениться. Проверить, какие версии библиотек являются актуальными, можно здесь.

1.3. Страницы: создание фрагментов


Фрагменты — это «страницы» нашего будущего приложения. Кликнув правой кнопкой на каталоге с файлами классов, командой «New → Fragment → Fragment (Blank)» создадим «Fragment1».

sewbwtqwvxhyi42or_lfl5juuxo.jpeg

etfft9mjbsbki2iwbzvzbngeume.png

IDE создаст kt-файл с классом фрагмента и xml-файл с макетом фрагмента. Таким же образом сгенерируем ещё три фрагмента («Fragment2», «Fragment3», «Fragment4»). Мы будем использовать их для создания четырёх разных типов навигации по приложению.

1.4. Адреса: файл ресурсов типа «Navigation»


Кликнув правой кнопкой мыши по папке «res», создадим файл ресурсов типа «Navigation» с названием «routes.xml» («маршруты»).

py5les6nwjvpmohzwdxb8lkbrh8.jpeg

imvxdjnujzax_tkcfkfikoiy_ds.png

Откроем созданный файл и с помощью кнопки «New Destination» добавим в навигационную схему наши фрагменты.

ebo_nyimkxdf27modgzkyvaqeku.jpeg

cf8rib6sf1ms_derrhadddnvu0y.jpeg

«Хватаясь» мышкой за точку в середине правой стороны фрагмента, соединим фрагменты друг с другом так, как они должны быть связаны в приложении.

8mmxccrg3_rwdof4k37zynhtbqs.jpeg

В соответствии с их названиями, наши фрагменты получат идентификаторы (id) «fragment1», «fragment2», «fragment3», «fragment4». Это «адреса», которые будут использоваться при указании пунктов назначения («destinations») в инструкциях навигационному контроллеру.

Кроме «id», каждый тег «fragment» содержит ещё три параметра: «name», «label» и «layout». Параметры «name» и «layout» нас сейчас не интересуют. Единственное, что стоит отредактировать в файле «routes.xml» — это названия («label») фрагментов. Заменим их на «Фрагмент №1», «Фрагмент №2», «Фрагмент №3» и «Фрагмент №4».

sxz5ub5avn0pg8igazl7x0mtxb8.jpeg

1.5. Фрейм: виджет NavHostFragment


Откроем файл макета «res/layout/activity_main.xml» и удалим текстовый виджет «Hello World!», он нам не понадобится. В палитре (Palette) выберем раздел «Контейнеры» (Containers) и перетащим оттуда на макет активности виджет NavHostFragment (указав наш файл «routes» в качестве источника информации для него). Он выполнит роль фрейма, в котором будут выводиться различные фрагменты приложения.

wpymkoyggi0d8slgx8ukbi7izs0.jpeg

tk0upfbtzqueh7wfzbheftlewxy.jpeg

Изменим id фрагмента на «navFragment». Код макета главной активности будет выглядеть теперь так:

lwxiipgxnutr4ykqdjzza8fgipq.jpeg

На этом подготовительные работы завершены, теперь можно приступать непосредственно к созданию элементов навигации.

Часть 2. Элементы навигации


2.1. Навигация с помощью кнопок


Откроем макет первого фрагмента («fragment_fragment1.xml»). Удалим ненужный текстовый виджет, изменим тип макета с «FrameLayout» на линейный вертикальный и добавим три кнопки с идентификаторами «button2», «button3», «button4» и соответствующими названиями «Фрагмент 2», «Фрагмент 3», «Фрагмент 4».

y3szz3qnrtnbbcya27usovnuvls.jpeg

В методе «onCreateView» фрагмента получим ссылку на навигационный контроллер (объект «NavController») и запрограммируем поведение при нажатии на кнопки: командой «setOnClickListener» для каждой кнопки создадим слушателя кнопки, который при клике по кнопке будет передавать навигационному контроллеру адрес (id) точки назначения вместе с командой переместиться (navigate) на указанный адрес.

5dhgqlykyyxsd3jcosrsg9ror-i.jpeg

Проверим, как работают наши кнопки.

vzutwhyelmhsvxsazmongd2xe0k.gif

Одна кнопка — одна строчка кода — и клик по кнопке перемещает нас к указанному фрагменту. Просто, не так ли?

Но без меню не очень удобно, приходится использовать кнопку «Назад» для возвращения на стартовый экран.

2.2. Боковое меню (drawer)


2.2.1. Ресурсный файл меню


В каталоге «res/menu» создадим ресурсный файл меню «drawer_menu.xml». Добавим в него пункты меню, каждый из которых представляет собой тег «item» с параметрами «id» (должен соответствовать таковому в навигационном графе «routes.xml», «title» (заголовок, он может быть другим), «icon» (мы используем одну и ту же картинку для всех пунктов, но, конечно же, они могут быть разными) и др. Наше меню будет выглядеть так:

tum6sjbwwrczhvemch9u5oabvqe.jpeg

2.2.2. Шаблон DrawerLayout и виджет NavigationView в макете активности


Откроем файл макета активности «activity_main.xml».
После первого тега (xml version…) добавим начало тега «DrawerLayout».

i9qeftpkkkz8lwfn515ry3gxw6i.jpeg

В конец файла добавим виджет «NavigationView» и окончание тега «DrawerLayout».

0vqunjv5ewao4dhc1btfheau7qo.jpeg

2.2.3. Подключение бокового меню в классе активности


Откроем файл «MainActivity.kt» и в методе «onCreate» получим ссылку на «navController» (в активности это выглядит чуть сложнее, чем было во фрагментах).

gntojdzx4nerc9ciukfay2rfszi.jpeg

Затем включим боковое меню:

a2itc51dgcpxk2po6ipmmyhufkm.jpeg

Код класса теперь выглядит так:

vrc_d94raagvogelkhtwrrtg89g.jpeg

Теперь меню появляется в ответ на свайп от левого края экрана:

rbfjktfx0ldbf9xcl4fyo8cbwq8.jpeg

Хорошо было бы добавить и кнопку слева-вверху для вызова бокового меню, верно?

2.3. Кнопка и название фрагмента на панели инструментов


Существующий по умолчанию ActionBar, как рекомендует официальное руководство, заменим на Toolbar.

Чтобы отключить существующий ActionBar, в файле «res/values/styles.xml» найдём строку