Bottom Sheet Navigation in Android App Development using Kotlin

Bottom Sheet Navigation in Android App Development using Kotlin: A Complete Guide

The Bottom Sheet Navigation is an increasingly popular UI component in modern Android apps. It slides up from the bottom of the screen and provides an easy way to access different app sections, actions, or contextual information. It’s commonly used in Material Design and is effective for giving users quick access to secondary screens without navigating away from the main content.

In this guide, we’ll explore how to implement Bottom Sheet Navigation in an Android app using Kotlin.


What is Bottom Sheet Navigation?

A Bottom Sheet Navigation is a sliding panel that appears from the bottom of the screen, displaying navigation options. It can be a modal or a persistent bottom sheet:

  • Modal Bottom Sheet: Appears temporarily as an overlay on top of other content and can be dismissed.
  • Persistent Bottom Sheet: Stays anchored at the bottom and is part of the main UI.

Android provides built-in support for bottom sheets with BottomSheetDialogFragment for modal sheets and BottomSheetBehavior for persistent sheets.


Prerequisites

To start, make sure you have:

  • Android Studio (latest version).
  • Material Components Library in your project’s dependencies, as it includes support for bottom sheets and other Material Design components.

Add the Material Components library to your build.gradle file in the dependencies section:

implementation 'com.google.android.material:material:<version>'

Replace <version> with the latest version available.


Step 1: Create a New Project

  1. Open Android Studio.
  2. Create a new project using the Empty Activity template.
  3. Choose Kotlin as the programming language.

Step 2: Design the Bottom Sheet Layout

Create a new layout file for the bottom sheet in res/layout. We’ll call this layout bottom_sheet_navigation.xml.

bottom_sheet_navigation.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/bottom_sheet_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Bottom Sheet Navigation"
        android:textSize="18sp"
        android:textStyle="bold"
        android:gravity="center"
        android:paddingBottom="16dp"/>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_home"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Home"/>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_profile"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Profile"/>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_settings"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Settings"/>
</LinearLayout>

This layout defines a simple vertical list of navigation items (buttons) in a bottom sheet.


Step 3: Create a BottomSheetDialogFragment Class

To display the bottom sheet, create a new Kotlin class called BottomNavigationDrawerFragment. This class will extend BottomSheetDialogFragment, which gives us a pre-configured modal bottom sheet.

BottomNavigationDrawerFragment.kt:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.bottom_sheet_navigation.*

class BottomNavigationDrawerFragment : BottomSheetDialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.bottom_sheet_navigation, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Set up click listeners for each button in the bottom sheet
        btn_home.setOnClickListener {
            // Navigate to Home
            // Handle the navigation action here
            dismiss() // Close the bottom sheet after selection
        }

        btn_profile.setOnClickListener {
            // Navigate to Profile
            dismiss()
        }

        btn_settings.setOnClickListener {
            // Navigate to Settings
            dismiss()
        }
    }
}

In this class:

  • We override onCreateView to inflate the bottom_sheet_navigation.xml layout.
  • In onViewCreated, we set up click listeners for each button to handle navigation.

Step 4: Launch the Bottom Sheet from MainActivity

In MainActivity, we’ll create a button or a toolbar icon that opens the bottom sheet when clicked.

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_show_bottom_sheet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Open Bottom Navigation"
        android:layout_centerInParent="true"/>
</RelativeLayout>

MainActivity.kt:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        // Show bottom sheet when the button is clicked
        btn_show_bottom_sheet.setOnClickListener {
            val bottomSheetFragment = BottomNavigationDrawerFragment()
            bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.tag)
        }
    }
}

In MainActivity, we set up a click listener on the button to display the BottomNavigationDrawerFragment.


Step 5: Create Fragment Classes for Each Destination

For each navigation destination, create a fragment class. We’ll create HomeFragment, ProfileFragment, and SettingsFragment.

Example: HomeFragment.kt:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class HomeFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }
}

Repeat this for ProfileFragment and SettingsFragment. Create corresponding layout files (fragment_home.xml, fragment_profile.xml, and fragment_settings.xml) in the res/layout directory.


Step 6: Handle Fragment Transactions in MainActivity

In BottomNavigationDrawerFragment, we need to replace the container’s content in MainActivity based on the user’s selection in the bottom sheet. Add fragment transaction handling code to replace the fragment in MainActivity.

Update BottomNavigationDrawerFragment as follows:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.bottom_sheet_navigation.*

class BottomNavigationDrawerFragment : BottomSheetDialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.bottom_sheet_navigation, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Handle each navigation option
        btn_home.setOnClickListener {
            openFragment(HomeFragment())
            dismiss()
        }

        btn_profile.setOnClickListener {
            openFragment(ProfileFragment())
            dismiss()
        }

        btn_settings.setOnClickListener {
            openFragment(SettingsFragment())
            dismiss()
        }
    }

    private fun openFragment(fragment: Fragment) {
        activity?.supportFragmentManager?.beginTransaction()
            ?.replace(R.id.fragment_container, fragment)
            ?.addToBackStack(null)
            ?.commit()
    }
}

In this version, openFragment takes a Fragment parameter and performs a fragment transaction in the MainActivity to display the selected fragment.


Step 7: Run the Application

Build and run the app on an emulator or physical device. You should see:

  • A button on the main screen to open the bottom sheet.
  • When you tap on the button, the bottom sheet navigation menu slides up from the bottom.
  • Tapping any button in the bottom sheet (Home, Profile, Settings) loads the corresponding fragment in the main content area.

Additional Tips

  1. Customizing the Bottom Sheet: You can further customize the appearance and behavior of the bottom sheet by setting properties in BottomSheetDialogFragment.
  2. Adding Animations: Android’s Transition framework allows you to add custom animations when switching between fragments.
  3. Using BottomSheetBehavior: For a persistent bottom sheet that remains visible, consider using BottomSheetBehavior to anchor it within the main content layout.

Conclusion

Implementing a bottom sheet navigation panel provides a user-friendly, visually appealing way to

allow navigation within your Android app. Using Kotlin and Material Components, you can easily integrate a bottom sheet for various navigation options while keeping the interface minimal and functional. With further customization and animations, you can refine the bottom sheet to create an engaging, high-quality user experience.

Happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *