
Bottom Sheet Navigation in Android App Development Using Java: A Complete Guide
Bottom Sheet Navigation is a popular UI component that slides up from the bottom of the screen, providing quick access to different parts of an app without requiring users to leave the current screen. This component is common in apps following Material Design guidelines, as it keeps navigation simple and intuitive. In this article, we’ll cover how to implement Bottom Sheet Navigation in an Android app using Java.
What is Bottom Sheet Navigation?
Bottom Sheet Navigation is a component that allows the user to access different app features or content by opening a panel from the bottom of the screen. There are two main types:
- Modal Bottom Sheet: Appears temporarily over the main content and can be dismissed by tapping outside or swiping down.
- Persistent Bottom Sheet: Stays anchored at the bottom of the screen and is part of the app’s permanent interface.
We’ll be creating a Modal Bottom Sheet for navigation in this guide, as it’s most commonly used for displaying navigational options without interrupting the main content.
Prerequisites
To start, make sure you have:
- Android Studio installed.
- Material Components Library added to your project dependencies for easy implementation of bottom sheets.
Add the Material Components library to your build.gradle
file under dependencies:
implementation 'com.google.android.material:material:<version>'
Replace <version>
with the latest version available.
Step 1: Set Up a New Project
- Open Android Studio.
- Create a new project with the Empty Activity template.
- Choose Java as the programming language.
Step 2: Design the Bottom Sheet Layout
Create a new layout file in the res/layout
directory for the bottom sheet navigation. We’ll call it 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 contains buttons for navigation options like “Home,” “Profile,” and “Settings.”
Step 3: Create the BottomSheetDialogFragment Class
Next, create a new Java class named BottomNavigationDrawerFragment
. This class should extend BottomSheetDialogFragment
, which allows us to display the layout as a modal bottom sheet.
BottomNavigationDrawerFragment.java:
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class BottomNavigationDrawerFragment extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.bottom_sheet_navigation, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set up click listeners for each button in the bottom sheet
view.findViewById(R.id.btn_home).setOnClickListener(v -> {
// Handle navigation to Home
dismiss(); // Close the bottom sheet after selection
});
view.findViewById(R.id.btn_profile).setOnClickListener(v -> {
// Handle navigation to Profile
dismiss();
});
view.findViewById(R.id.btn_settings).setOnClickListener(v -> {
// Handle navigation to Settings
dismiss();
});
}
}
This class does the following:
- Overrides
onCreateView
to inflate the bottom sheet layout. - Adds click listeners for each button to handle navigation actions.
Step 4: Trigger the Bottom Sheet in MainActivity
Now, let’s add a button or toolbar icon in MainActivity
to open the bottom sheet. In this example, we’ll add a button in the main activity layout.
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.java:
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Show bottom sheet when the button is clicked
findViewById(R.id.btn_show_bottom_sheet).setOnClickListener(v -> {
BottomNavigationDrawerFragment bottomSheetFragment = new BottomNavigationDrawerFragment();
bottomSheetFragment.show(getSupportFragmentManager(), bottomSheetFragment.getTag());
});
}
}
In MainActivity
, we set up a click listener on the button to display the BottomNavigationDrawerFragment
.
Step 5: Create Fragment Classes for Each Navigation Destination
Now, create fragment classes for each destination. We’ll create HomeFragment
, ProfileFragment
, and SettingsFragment
.
Example: HomeFragment.java:
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class HomeFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
}
Repeat this process to create ProfileFragment
and SettingsFragment
. Add corresponding layout files (fragment_home.xml
, fragment_profile.xml
, fragment_settings.xml
) in the res/layout
folder.
Step 6: Handle Fragment Transactions in MainActivity
To switch fragments based on the bottom sheet selections, add fragment handling code in BottomNavigationDrawerFragment
.
Update BottomNavigationDrawerFragment
as follows:
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class BottomNavigationDrawerFragment extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.bottom_sheet_navigation, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btn_home).setOnClickListener(v -> {
openFragment(new HomeFragment());
dismiss();
});
view.findViewById(R.id.btn_profile).setOnClickListener(v -> {
openFragment(new ProfileFragment());
dismiss();
});
view.findViewById(R.id.btn_settings).setOnClickListener(v -> {
openFragment(new SettingsFragment());
dismiss();
});
}
private void openFragment(Fragment fragment) {
if (getActivity() != null) {
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
}
}
In this version, openFragment
is a helper method that performs the fragment transaction to display the selected fragment in the main content area.
Step 7: Run the Application
Now, build and run your app. You should see:
- A button in the main activity layout that, when tapped, opens the bottom sheet.
- A bottom sheet panel with navigation buttons for Home, Profile, and Settings.
- Selecting any button loads the corresponding fragment in the main content area of
MainActivity
.
Additional Tips
- Customizing the Bottom Sheet: You can modify
BottomSheetDialogFragment
to apply additional styles or behaviors. - **Persistent Bottom Sheet**: For a persistent bottom sheet, consider using
BottomSheetBehavior
and placing the layout inactivity_main.xml
. - Animations and Custom Styling: Customize animations and transitions for a smoother UI experience using Android’s
Transition
framework.
Conclusion
With the Bottom Sheet Navigation component, you can simplify your app’s navigation structure and provide users with easy access to key app sections. Implementing it in Java is straightforward and offers a modern, intuitive design that aligns well with Material Design principles.