Implementing DrawerLayout for Tablet and BottomNavigationView for Mobile Screens in Android
1. Introduction
In Android development, it's essential to design user interfaces that adapt to various screen sizes, including mobile phones and tablets. A common design pattern involves using a BottomNavigationView
for mobile screens and a DrawerLayout
for tablets. This approach ensures optimal navigation experiences tailored to the device's screen size.
This document outlines the implementation of a DrawerLayout
for tablet screens and a BottomNavigationView
for mobile screens in an Android application, along with best practices and code examples.
2. Understanding DrawerLayout
and BottomNavigationView
2.1 DrawerLayout
DrawerLayout
is a layout that allows developers to implement a sliding drawer that can contain navigation items. It is typically used in tablet designs to utilize the larger screen space effectively.
2.2 BottomNavigationView
BottomNavigationView
is a bar at the bottom of the screen that provides easy access to primary navigation destinations. It is ideal for mobile devices where space is limited.
3. Adaptive UI Design
3.1 Screen Size Configuration
To differentiate between mobile and tablet devices, Android developers use configuration qualifiers such as sw600dp
(smallest width of 600dp) for tablets. This allows the app to load different layouts depending on the screen size.
3.2 XML Layout Files
Mobile Layout (default):
- Use a
BottomNavigationView
at the bottom of the screen.
- Use a
Tablet Layout (
res/layout-sw600dp
):- Use a
DrawerLayout
with a navigation drawer.
- Use a
3.3 Example Layout Files
Main Layout (Mobile) - res/layout/activity_main.xml
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Main Content -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Bottom Navigation View -->
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="@menu/bottom_nav_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
Main Layout (Tablet) - res/layout-sw600dp/activity_main.xml
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Toolbar for Tablet -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
<!-- Main Content -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Navigation Drawer -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
4. Java Implementation
4.1 MainActivity.java
This is the main activity where the DrawerLayout
and BottomNavigationView
are managed. The code below demonstrates how to handle both navigation patterns based on the device type.
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
private NavigationView navigationView;
private BottomNavigationView bottomNavigationView;
private ActionBarDrawerToggle toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Toolbar setup for Drawer
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.nav_view);
bottomNavigationView = findViewById(R.id.bottom_navigation);
// Setup Drawer Toggle
toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
// Drawer Menu Item Selection Handling
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_home) {
// Handle Home navigation
} else if (id == R.id.nav_profile) {
startActivity(new Intent(getApplicationContext(), ProfileActivity.class));
} else if (id == R.id.nav_settings) {
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
} else if (id == R.id.nav_help) {
startActivity(new Intent(getApplicationContext(), HelpActivity.class));
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
// Bottom Navigation Setup
bottomNavigationView.setSelectedItemId(R.id.nav_home); // Home page selected by default
bottomNavigationView.setOnItemSelectedListener(menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.nav_home) {
// Empty when currently selected.
return true;
} else if (id == R.id.nav_news) {
startActivity(new Intent(getApplicationContext(), NewsActivity.class)); // Starts the News activity
overridePendingTransition(0, 0); // Removes the sliding animation
finish();
return true;
} else if (id == R.id.nav_settings) {
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
overridePendingTransition(0, 0);
finish();
return true;
}
return false;
});
// Determine if running on a tablet
boolean isTablet = getResources().getBoolean(R.bool.isTablet);
if (isTablet) {
bottomNavigationView.setVisibility(View.GONE); // Hide BottomNavigationView on tablets
} else {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); // Lock the Drawer closed on phones
}
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (toggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
4.2 Explanation
Drawer Toggle: The
ActionBarDrawerToggle
is used to open and close the navigation drawer with the hamburger icon.Responsive Design: The application checks if it's running on a tablet or mobile. On tablets, the
BottomNavigationView
is hidden, and the drawer is unlocked. On mobile, the drawer is locked, and theBottomNavigationView
is visible.Navigation Handling: Both the drawer and bottom navigation handle user navigation seamlessly.
5. Testing and Validation
5.1 Testing on Multiple Devices
Testing should be conducted on both tablet and mobile devices to ensure the layouts adapt correctly to different screen sizes. This includes checking:
Drawer behavior on tablets.
Bottom navigation visibility on mobile devices.
Correct handling of back navigation.
5.2 Unit Testing and UI Testing
Unit tests should be written to ensure navigation actions are handled as expected. UI testing using Espresso can validate the visibility and interactions of UI elements like the drawer and bottom navigation.
6. Conclusion
Implementing a DrawerLayout
for tablets and BottomNavigationView
for mobile screens allows Android applications to provide a user-friendly and device-specific navigation experience. By leveraging configuration qualifiers and adaptive layouts, developers can create applications that look and function well on both large and small screens.
7. References
This research document should give you a comprehensive understanding of how to implement adaptive navigation patterns in an Android application, catering to both mobile and tablet