Урок 19. Как создать андроид-приложение с вкладками – TabLayout с ViewPager2 на Kotlin

На прошлом уроке мы познакомились с ViewPager2 и создали андроид-приложение, в котором можно листать экраны свайпом вправо или влево. На этом уроке добавим в верхней части экрана вкладки, которые будут содержать заголовки и индикатор экрана, на котором находится пользователь в данный момент, а также рассмотрим некоторые их свойства и способы оформления.

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

Добавление TabLayout в макет разметки экрана

Чтобы добавить вкладки на экран, нужно открыть макет разметки и добавить компонент com.google.android.material.tabs.TabLayout в верхней части экрана:

Для корректного размещения нужно изменить компонент ViewPager2 – высоту укажем 0dp. Таким образом, высоту компонента будет регулировать корневой ConstraintLayout по заданным ограничениям. А вместо ограничения app:layout_constraintTop_toTopOf=»parent» поставим app:layout_constraintTop_toBottomOf=»@+id/tab_layout» – чтобы верх компонента ViewPager2 был ограничен не верхней границей родительского компонента, а нижней границей компонента TabLayout.

Рассмотрим подробнее компонент com.google.android.material.tabs.TabLayout. Свойство app:tabMode=»scrollable» обеспечивает размещение в видимой части экрана только нескольких вкладок, остальные будут доступны в процессе прокрутки. Если мы не укажем это свойство, то в видимой части экрана будут одновременно отображаться все вкладки, и при большом их количестве визуальное восприятие будет затруднено.

Свойство app:tabIndicatorColor=»@color/teal_200″ указывает цвет, а app:tabIndicatorHeight=»4dp» – толщину индикатора вкладки.

Далее идут свойства ширины – указываем по родителю – и высоты – указываем по содержимому.

Последние три свойства – ограничения верхней части и боковых сторон компонента по родителю.

Реализация вкладок в MainActivity

Открываем класс MainActivity и пишем реализацию вкладок:

Инициализируем TabLayout так же, как мы это делали с ViewPager2 на прошлом уроке. Сначала объявляем переменную с ленивой инициализацией. В onCreate находим компонент TabLayout по идентификатору в макете разметки и связываем его с переменной.

Для синхронизации компонента TabLayout с ViewPager2, установки текста заголовков вкладок, а также стиля вкладок, используется класс TabLayoutMediator. Судя из его названия, это посредник, который выполняет связывание и согласование позиций списка вкладок со списком страниц ViewPager2, он слушает коллбек ViewPager2 и в соответствии с прокруткой страниц прокручивает и вкладки.

В данном случае мы обращаемся к свойству tab.text и передаем в заголовки одинаковый текст – слово «TAB» —  с номером вкладки. Во второй половине урока модифицируем этот участок кода для передачи разного текста в заголовки вкладок.

Метод attach() связывает TabLayout с ViewPager2.

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

Реализация вкладок в MainActivity

Уникальные имена для вкладок

А что, если нам нужно присвоить вкладкам уникальные имена? Давайте это реализуем.

Изменим код класса MainActivity:

Мы создаем строковый массив tabNames с набором собственных имен для каждой вкладки. Затем присваиваем имена вкладкам: tab.text = tabNames[position]. Поскольку позиция вкладки служит нам индексом для обращения к элементам массива, имена в массиве должны располагаться в том же порядке.

Мы здесь создали массив имен только из десяти элементов, и во избежание ошибки нужно также ограничить десятью и количество вкладок. Мы определили количество вкладок на прошлом уроке в классе NumberAdapter, в методе getItemCount() — проверьте и исправьте:

После запуска приложения на устройстве мы видим экран с десятью прокручиваемыми вкладками и уникальными именами заголовков.

Уникальные имена для вкладок

Отключение капса в заголовках вкладок

Заголовки по умолчанию отображаются капсом. Если вам нужно, чтобы они отображались как обычный текст, нужно создать собственный стиль в файле themes.xml:

Это вернет текст в нормальное состояние. Почему нужно указывать сразу два свойства? Это связано с особенностями работы разных версий библиотек материального дизайна.

Теперь созданный стиль нужно применить компоненту TabLayout в activity_main.xml:

Вуаля:

Отключение капса в заголовках вкладок

Таким образом можно создавать собственные стили и кастомизировать не только текст, но и другие свойства вкладок.

Бейджи для вкладок

Также вкладкам можно устанавливать бейджи, для этого измените код TabLayoutMediator  в классе MainActivity:

Здесь мы в заголовок третьей вкладки добавляем бейдж с числом 1. Удалить бейджи можно методом tab.removeBadge().

Бейджи для вкладок

Иконки заголовков вкладок

Можно также установить иконки в заголовках вкладок, вместо текста или вместе с ним.

Добавим в MainActivity массив со ссылками на иконки:

Иконки были предварительно скачаны с сайта материального дизайна и сохранены в папку res/drawable нашего проекта. Вы можете взять их из исходников или скачать по ссылке.

Поскольку иконок всего шесть, во избежание ошибки измените на шесть количество вкладок в методе getItemCount() класса NumberAdapter.

Теперь можно установить иконки для вкладок методом tab.setIcon(tabNumbers[position]):

Вот что должно получиться при запуске приложения:

Иконки заголовков вкладок

Если удалить или закомментировать строку tab.text = tabNames[position], то в заголовках вкладок останутся только иконки:

Иконки заголовков вкладок

Исходный код

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

Добавить комментарий