Bottom Navigation: Basics, BottomNavigationView and TabView

Author: IT Sectr Published: 2026-02-23 Reading time: 11 min

Bottom Navigation is a navigation pattern where the section switching panel is located at the bottom of the screen. In Android it is implemented via BottomNavigationView (Material 3), in iOS — via UITabBarController or TabView in SwiftUI. Learn more about the Material Design specification in the Material Design 3 documentation.

Key Takeaways

  • Bottom Navigation — bottom panel for switching between 3–5 main app sections
  • BottomNavigationView — Android Material 3 component with three label display modes
  • TabView — built-in SwiftUI container for creating bottom navigation with tabs
  • NavigationView + TabView — combination for stack navigation within each tab
  • Material 3 — support for dynamic colors, indicator animation, and badges

What is Bottom Navigation?

Bottom Navigation is a navigation pattern where the main app sections are accessible via a panel at the bottom of the screen. This pattern has become a mobile design standard due to its one-handed usability. Unlike a side menu (Drawer), Bottom Navigation is always visible and does not require additional gestures to open.

Material Design 3 (2026) defines the Navigation Bar as a component with three states: default (icon + label), labeled (enlarged label, one active tab), and unlabeled (icons only). Google recommends Navigation Bar for apps with 3–5 equal sections. For 6+ sections — Navigation Drawer. In iOS SwiftUI, TabView automatically uses a bottom panel with system style.

A UX Movement study (2025) showed that Bottom Navigation improves task completion time by 27% compared to a side drawer, since the user sees all available sections without additional actions. Incorrect tap count decreases by 34% thanks to large touch targets (minimum 48x48 dp on Android, 44x44 pt on iOS).

BottomNavigationView in Android (Material 3)

BottomNavigationView in Android is a component from the Material 3 Library (com.google.android.material.navigation.NavigationBarView). It replaced the legacy BottomNavigationView from Material 2 and added support for Material You dynamic colors, animated active tab indicator, and built-in badges. The component is configured via XML menu and is fully compatible with Navigation Component.

kotlin
// Activity with BottomNavigationView and NavHostFragment
class MainActivity : AppCompatActivity() {

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

        val navView = findViewById<NavigationBarView>(R.id.nav_view)
        val navController = findNavController(R.id.nav_host_fragment)

        // Automatic navigation synchronization
        navView.setupWithNavController(navController)

        // Badge setup
        val badge = navView.getOrCreateBadge(R.id.navigation_messages)
        badge.number = 8
        badge.badgeGravity = BadgeDrawable.TOP_END
    }
}

// XML menu for Bottom Navigation (res/menu/bottom_nav_menu.xml)
// <?xml version="1.0" encoding="utf-8"?>
// <menu xmlns:android="http://schemas.android.com/apk/res/android">
//   <item android:id="@+id/navigation_home"
//     android:icon="@drawable/ic_home"
//     android:title="Home" />
//   <item android:id="@+id/navigation_messages"
//     android:icon="@drawable/ic_chat"
//     android:title="Chats" />
//   <item android:id="@+id/navigation_profile"
//     android:icon="@drawable/ic_person"
//     android:title="Profile" />
// </menu>

Material 3 NavigationBarView supports three labelVisibilityMode modes: LABEL_VISIBILITY_AUTO (default — label is shown for the active tab), LABEL_VISIBILITY_LABELED (labels for all), LABEL_VISIBILITY_UNLABELED (icons only). The animated active tab indicator is configured via itemActiveIndicatorStyle with a custom ripple effect.

TabView in SwiftUI for iOS

TabView is a built-in SwiftUI container for creating bottom navigation. Each tab is defined using the .tabItem modifier with an icon and text. TabView automatically creates a UITabBarController under the hood and supports all native panel features: badges, badge color, switching animation, and Dynamic Type adaptation.

swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            HomeView()
                .tabItem {
                    Label("Home", systemImage: "house.fill")
                }
                .badge(3)

            SearchView()
                .tabItem {
                    Label("Search", systemImage: "magnifyingglass")
                }

            NotificationsView()
                .tabItem {
                    Label("Notifications", systemImage: "bell.fill")
                }
                .badge("12")

            ProfileView()
                .tabItem {
                    Label("Profile", systemImage: "person.circle.fill")
                }
        }
    }
}

TabView supports the .badge modifier (iOS 15+), which accepts Int (numeric badge) or String (text badge). Badge color can be changed via .badgeProminence(.increased) — makes the badge brighter. Tab switching animation is configured via .tabViewStyle(.automatic) or custom styles. For programmatic switching control, @State with selection is used.

Combining Bottom and Stack Navigation

Bottom Navigation is rarely used alone — each tab usually contains a stack navigator (NavigationView/NavigationStack in SwiftUI, NavHostFragment in Android). This combination gives the user both quick access to sections (Tab) and deep navigation within each section (Stack). This is the standard architecture for production apps.

swift
struct AppTabView: View {
    var body: some View {
        TabView {
            NavigationStack {
                HomeView()
            }
            .tabItem {
                Label("Home", systemImage: "house")
            }

            NavigationStack {
                SearchView()
            }
            .tabItem {
                Label("Search", systemImage: "magnifyingglass")
            }
        }
    }
}

// Inside HomeView — stack navigation
struct HomeView: View {
    var body: some View {
        List(items) { item in
            NavigationLink("\(item.title)", value: item)
        }
        .navigationDestination(for: Item.self) { item in
            ItemDetailView(item: item)
        }
    }
}

In Android, the same combination is implemented via NavHostFragment for each tab. Navigation Component automates back stack creation for each tab: when switching tabs, the stack state is preserved, and when returning — restored. This provides a seamless UX, like in Google system apps (Play Market, YouTube).

Material 3: Dynamic Colors and Animations

Material 3 (Material You) introduces a key change to Bottom Navigation — dynamic colors generated from the user's wallpaper. The system extracts dominant colors from the wallpaper and creates a palette of 5 key tones. NavigationBarView automatically applies these colors: the active tab receives the primary color, inactive tabs — onSurface variant.

The active tab indicator animation has become smooth: when switching, the indicator animates to the new tab with interpolation. The touch ripple effect uses the secondary color. Bottom Navigation in Material 3 also supports custom animations via itemActiveIndicatorStyle — the developer can set the shape (oval, rectangle), padding, and indicator color.

xml
<!-- Active indicator style for NavigationBarView -->
<style name="Widget.MyApp.NavigationBarView.ActiveIndicator"
    parent="Widget.Material3.NavigationBarView.ActiveIndicator">
    <item name="android:height">32dp</item>
    <item name="android:width">64dp</item>
    <item name="android:marginHorizontal">8dp</item>
    <item name="shapeAppearance">
        @style/ShapeAppearance.Material3.Corner.Full
    </item>
    <item name="color">@color/primary_container</item>
</style>

UX Recommendations for Bottom Navigation

When designing Bottom Navigation, usability research should be considered. NN Group (2026): the bottom panel should be at least 56 dp high, touch targets — at least 48 dp. Label text — maximum 12 characters (Latin) or 8 characters (Cyrillic). The active tab should differ not only in color but also in icon state (filled vs outlined).

Material Design 3 recommends the following patterns: 4 tabs — optimal for easy scanning; a "+" icon in the center (FloatingActionButton) — for the primary action; badges — only for user action counters. Avoid: using Bottom Navigation with 2 tabs (use Tab Layout instead), dynamically changing tab order, hiding the panel on nested screens.

  • Height — minimum 56 dp for comfortable thumb reach
  • Contrast — active tab should be distinguishable (color + icon fill)
  • Labels — short, 1-2 words, no truncation (no more than 12 characters)
  • Order — fixed, from most important to least important
  • Counters — only for user notifications, not for marketing

Frequently Asked Questions

What is the difference between Bottom Navigation and Navigation Drawer?

Bottom Navigation — a panel at the bottom of the screen, always visible, for 3–5 equal sections. Navigation Drawer — a side menu invoked by gesture or button, for 6+ sections, settings, and secondary pages. Drawer hides content, Bottom Navigation does not.

How many tabs are optimal for Bottom Navigation?

4 tabs — optimal according to NN Group data. 3 — minimum to justify a bottom panel. 5 — maximum where all tabs remain distinguishable. 6+ requires switching to Navigation Drawer or a "More" item on iOS.

How to implement a badge on BottomNavigationView?

In Android Material 3, use getOrCreateBadge(itemId) on NavigationBarView. Configure the number via badge.number and position via badgeGravity (TOP_END, TOP_START). In iOS SwiftUI — the .badge(Int) modifier on .tabItem. In UIKit — tabBarItem.badgeValue = "N".

Can tab switching be animated?

Yes. Material 3 NavigationBarView animates the active tab indicator movement. SwiftUI TabView uses the system iOS animation. For custom content animations, use matchedGeometryEffect (SwiftUI) or Transition (Jetpack Compose). The panel switching animation itself is system-based.

Is Bottom Navigation suitable for web apps?

Yes, for mobile-first and PWA. Material Design 3 has a web Navigation Bar component. However, on desktop, it is better to use a side panel (Side Navigation) — horizontal space allows showing more items. Bottom Navigation on desktop is an anti-pattern.

Summary

  • Bottom Navigation — standard mobile navigation pattern for 3–5 main sections
  • NavigationBarView (Android Material 3) and TabView (iOS SwiftUI) — modern implementations
  • Material 3 Dynamic Colors — automatic color palette generation from user wallpaper
  • Tab + Stack — combination of bottom navigation with stack navigation inside each tab for production architecture
  • Indicator Animation — smooth active indicator movement when switching tabs
  • UX Rules — height 56 dp, 4 tabs, fixed order, contrasting active tab
  • Badges — built-in support for numeric and dot indicators on both platforms

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also