Android SharedPreferences Tutorial and Example

Designing a Material Design Bottom Navigation Bar

A bottom navigation bar gives users fast access to the main destinations in an Android app. It works especially well when those destinations are independent, such as Home, Search, Favourites and Profile. Material Design provides familiar spacing, colour, elevation and interaction patterns so the control feels consistent across phones and tablets.

For modern Android projects, use Material 3 components with Kotlin and XML or Jetpack Compose. The same principles apply to both approaches: keep navigation destinations limited, use recognisable icons, show the selected state clearly, and preserve each screen’s state when users move between sections.

This pattern suits everyday Australian mobile use, where people may check an app while commuting through Sydney, waiting for a tram in Melbourne or using a phone in a busy shopping centre. A compact navigation control reduces taps and keeps essential features reachable with one hand.

Choose the right destinations

Bottom navigation is intended for three to five top-level destinations. Each item should represent a major area of the application rather than an individual action. For example, a budgeting app might use Overview, Transactions, Goals and Settings, while a recipe app could use Discover, Saved, Shopping List and Account.

Avoid placing tasks such as “Add payment” or “Delete item” in the bar. These actions belong inside the relevant screen, usually as a floating action button, toolbar action or clearly labelled button. Mixing destinations and commands makes the navigation model harder to understand.

Use short labels and familiar icons. A house for Home and a person silhouette for Profile are easy to recognise, but an unfamiliar icon should have a visible text label. This is particularly useful for older users and people using accessibility services.

Add Material components to the project

In an XML-based Android application, add the Material Components dependency to the module-level Gradle file. Use a current stable release that matches the rest of the project.

dependencies {
    implementation("com.google.android.material:material:<version>")
}

A typical layout places BottomNavigationView beneath a FragmentContainerView. ConstraintLayout keeps the navigation bar attached to the bottom while allowing the content area to expand.

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:menu="@menu/main_navigation"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

Create the menu in res/menu/main_navigation.xml. Each item needs a stable ID, an icon and a short title. Vector drawables are preferable because they scale cleanly across different screen densities.

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/home"
        android:icon="@drawable/ic_home"
        android:title="@string/home" />

    <item
        android:id="@+id/search"
        android:icon="@drawable/ic_search"
        android:title="@string/search" />

    <item
        android:id="@+id/profile"
        android:icon="@drawable/ic_person"
        android:title="@string/profile" />
</menu>

Connect the bar to navigation

With the Android Navigation Component, connect the menu item IDs to destinations in the navigation graph. The IDs must match; otherwise, selecting an item will not open the expected destination.

val navController = findNavController(R.id.nav_host_fragment)

binding.bottomNavigation.setupWithNavController(navController)

setupWithNavController keeps the selected item aligned with the current destination, including when the user presses the system Back button or navigates through a deep link. This is safer than manually replacing fragments without updating the selected state.

If the application uses Compose, NavigationBar provides the Material 3 equivalent. Store the selected route in navigation state and call navController.navigate() when an item is selected. Configure launchSingleTop, restoreState and popUpTo where appropriate to avoid creating duplicate destinations.

Requirement Recommended approach Common mistake
Three to five main areas Use top-level destinations Adding every feature as an item
Selected state Connect the bar to NavController Updating icon colour manually only
Icons Use accessible vector drawables Relying on colour without a label
Screen state Save and restore navigation state Resetting forms on every tap
Responsive layout Respect insets and large screens Letting content hide behind the bar

Apply Material styling and accessibility

Material 3 themes let the navigation bar inherit surface, primary and on-surface colours from the application colour scheme. The active destination should have a clear indicator, while inactive destinations need enough contrast to remain readable. Test the design in both light and dark themes.

Do not use colour as the only signal for selection. The icon, label and indicator should work together. Ensure touch targets are at least 48dp high and avoid placing important controls too close to the navigation bar, gesture area or device edge.

Set meaningful content descriptions for icons when they are not accompanied by visible text. Test with TalkBack, Android’s screen reader, and with large font settings. These checks support users with disabilities and align with accessibility expectations relevant to Australian services under the Disability Discrimination Act 1992.

Handle state, badges and system insets

A polished bottom navigation bar preserves useful state. If a user enters a search query, scrolls through a feed or fills out a form, changing destinations should not unexpectedly erase that work. Navigation fragments, saved state handles and ViewModels can help retain data safely.

Badges are useful for unread messages or pending tasks, but they should be restrained. A badge containing “9+” is easier to scan than a long number, and it should have an accessible description such as “Nine or more unread notifications.” Never use a badge to communicate urgent information that users might miss.

Apply window insets so content does not overlap the navigation control, especially on phones using gesture navigation. Test edge-to-edge layouts on devices with different aspect ratios. This matters for users moving between compact phones and large-screen devices commonly used for maps, shopping and banking.

Test for the Australian market

Test the app on a range of screen sizes and network conditions, including slower connections that users may encounter on regional roads or in crowded venues. Check the bar on popular Android form factors used in Brisbane, Perth and Adelaide, rather than relying only on an emulator with a standard display.

Use Australian English in labels and supporting text where appropriate, and verify dates, currency and address forms elsewhere in the app. If the navigation leads to account, payment or location features, explain data collection clearly and handle personal information according to the Australian Privacy Principles under the Privacy Act 1988.

Local users often expect quick interactions while travelling on public transport or comparing products in a retail app. Keep destinations available offline when practical, show a clear loading state, and avoid hiding the bar during routine browsing. Before release, test TalkBack navigation, dark mode, rotation, font scaling, deep links and process recreation so the selected destination remains reliable.