0Pricing
Android Academy · Урок

Нижняя навигация и вкладки

Реализуйте навигацию по разделам с помощью BottomNavigationView, подключённого к NavController, а также вкладки с пролистыванием через TabLayout, ViewPager2 и TabLayoutMediator.

«Нижняя навигация и вкладки» — бесплатный урок Android Academy на CoddyKit. Это урок 5 из 5. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 5 уроков всего.

Шаблоны навигации

Два распространённых шаблона навигации верхнего уровня в приложениях Android:

  • Нижняя навигация — для 3–5 основных разделов. Всегда видна. Лучше всего подходит для разделов одинаковой важности (например, «Главная», «Поиск», «Профиль»).
  • Вкладки — для связанного содержимого на одном экране (например, «Все» / «Активные» / «Выполненные»). Часто используются вместе с ViewPager2 для поддержки перелистывания.

Разметка BottomNavigationView

Добавьте BottomNavigationView и FragmentContainerView в разметку Activity:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/navHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:menu="@menu/bottom_nav_menu" />

</LinearLayout>

Пункты меню нижней навигации

Определите пункты в res/menu/bottom_nav_menu.xml. ID каждого пункта должен совпадать с ID назначения в графе навигации:

<!-- res/menu/bottom_nav_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/homeFragment"
        android:icon="@drawable/ic_home"
        android:title="Home" />
    <item
        android:id="@+id/searchFragment"
        android:icon="@drawable/ic_search"
        android:title="Search" />
    <item
        android:id="@+id/profileFragment"
        android:icon="@drawable/ic_person"
        android:title="Profile" />
</menu>

Подключение к NavController

Свяжите BottomNavigationView с NavController в onCreate():

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val navHost = supportFragmentManager
            .findFragmentById(R.id.navHostFragment) as NavHostFragment
        val navController = navHost.navController

        binding.bottomNav.setupWithNavController(navController)

        // Hide bottom nav on detail screens:
        navController.addOnDestinationChangedListener { _, destination, _ ->
            binding.bottomNav.visibility = when (destination.id) {
                R.id.detailFragment -> View.GONE
                else -> View.VISIBLE
            }
        }
    }
}

Значки в нижней навигации

Показывайте значки уведомлений на пунктах нижней навигации:

// Show a numbered badge:
val badge = binding.bottomNav.getOrCreateBadge(R.id.homeFragment)
badge.number = 5
badge.isVisible = true

// Show dot badge (no number):
val dotBadge = binding.bottomNav.getOrCreateBadge(R.id.searchFragment)
dotBadge.isVisible = true

// Remove badge:
binding.bottomNav.removeBadge(R.id.homeFragment)

TabLayout

TabLayout отображает горизонтальные вкладки и обычно используется вместе с ViewPager2 для содержимого, которое можно перелистывать:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

ViewPager2 + FragmentStateAdapter

Создайте адаптер, который предоставляет фрагмент для каждой позиции вкладки:

class TasksPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    override fun getItemCount() = 3

    override fun createFragment(position: Int): Fragment = when (position) {
        0 -> AllTasksFragment()
        1 -> ActiveTasksFragment()
        2 -> CompletedTasksFragment()
        else -> throw IllegalStateException("Unknown tab $position")
    }
}

TabLayoutMediator

Соедините ViewPager2 и TabLayout с помощью TabLayoutMediator:

// In Fragment.onViewCreated():
val adapter = TasksPagerAdapter(this)
binding.viewPager.adapter = adapter

TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
    tab.text = when (position) {
        0 -> "All"
        1 -> "Active"
        2 -> "Done"
        else -> ""
    }
}.attach()

// Disable swipe if needed:
binding.viewPager.isUserInputEnabled = false

Вкладки со значками

Добавьте значки на вкладки TabLayout:

TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
    when (position) {
        0 -> {
            tab.text = "Home"
            tab.setIcon(R.drawable.ic_home)
        }
        1 -> {
            tab.text = "Search"
            tab.setIcon(R.drawable.ic_search)
        }
        2 -> {
            tab.text = "Profile"
            tab.setIcon(R.drawable.ic_person)
        }
    }
}.attach()

Лимит страниц за пределами экрана

По умолчанию ViewPager2 хранит в памяти только соседнюю страницу. Увеличьте offscreenPageLimit, если вкладки должны оставаться активными при переключении:

// Keep 2 pages on each side alive:
binding.viewPager.offscreenPageLimit = 2

// Note: FragmentStateAdapter saves and restores state for off-screen
// fragments even when offscreenPageLimit is 1 (default).
// Only increase this when you need views (not just state) to survive.

Нижняя навигация или вкладки: выбор

Краткое руководство по выбору подходящего шаблона:

  • Используйте нижнюю навигацию, если: есть 3–5 разделов верхнего уровня с разным назначением («Главная», «Поиск», «Уведомления», «Профиль»)
  • Используйте вкладки, если: нужно фильтровать или распределять по категориям однотипное содержимое (все / активные / архивные задачи)
  • Сочетайте оба варианта: нижняя навигация — для разделов верхнего уровня, вкладки внутри раздела — для дополнительной фильтрации

Быстрая проверка

Какой класс соединяет TabLayout с ViewPager2 и задаёт названия вкладок?

Итоги: нижняя навигация и вкладки

Правильная навигация по нескольким разделам:

  • BottomNavigationView — 3–5 равнозначных разделов, ID пунктов меню совпадают с ID назначений в графе навигации
  • setupWithNavController() — автоматическое переключение вкладок и работа с back stack
  • Значки с помощью getOrCreateBadge()
  • TabLayout + ViewPager2 — перелистываемые представления одного и того же содержимого с фильтрацией
  • TabLayoutMediator — соединяет их и задаёт названия

Далее: модульное тестирование с JUnit для повышения надёжности кода.

Часто задаваемые вопросы

Урок «Нижняя навигация и вкладки» бесплатный?

Да — полный текст урока «Нижняя навигация и вкладки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 5 уроков всего.

Чему я научусь в уроке «Нижняя навигация и вкладки»?

Реализуйте навигацию по разделам с помощью BottomNavigationView, подключённого к NavController, а также вкладки с пролистыванием через TabLayout, ViewPager2 и TabLayoutMediator. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 5 из 5.

Сколько времени занимает урок «Нижняя навигация и вкладки»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы Material Design
  2. Темы и стили
  3. Пользовательские представления
  4. Анимации и переходы
  5. Нижняя навигация и вкладки
← Назад к Android Academy