Giới thiệu
NavigationView (thường gọi là Navigation Drawer / Side Menu) là thành phần UI Material Design chuẩn cho điều hướng chính của ứng dụng. Bài viết hướng dẫn triển khai Navigation Drawer với DrawerLayout, NavigationView, Toolbar, Fragment và Navigation Component (Jetpack).
Các bước thực hiện
Bước 1: Tạo dự án mới
Android Studio → File → New Project → Chọn **Navigation Drawer Activity** (template có sẵn toàn bộ code).
Hoặc Empty Activity + thêm dependency:
dependencies {
implementation 'androidx.navigation:navigation-fragment:2.7.6'
implementation 'androidx.navigation:navigation-ui:2.7.6'
implementation 'com.google.android.material:material:1.11.0'
}
Bước 2: Layout chính (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- Navigation Drawer (Menu bên cạnh) -->
<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"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
<!-- Nội dung chính (toolbar + fragment container) -->
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.drawerlayout.widget.DrawerLayout>
Bước 3: App Bar Layout (res/layout/app_bar_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<!-- Fragment container - Navigation Host -->
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Bước 4: Header Drawer (res/layout/nav_header_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:background="@drawable/nav_header_bg"
android:gravity="bottom"
android:orientation="vertical"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:src="@mipmap/ic_launcher_round"
android:contentDescription="@string/app_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Nguyễn Văn A"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="nguyenvana@example.com" />
</LinearLayout>
Bước 5: Menu Drawer (res/menu/activity_main_drawer.xml)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_home"
android:title="Trang chủ" />
<item
android:id="@+id/nav_gallery"
android:icon="@drawable/ic_gallery"
android:title="Thư viện" />
<item
android:id="@+id/nav_slideshow"
android:icon="@drawable/ic_slideshow"
android:title="Slideshow" />
<item
android:id="@+id/nav_tools"
android:icon="@drawable/ic_tools"
android:title="Công cụ" />
<item
android:id="@+id/nav_share"
android:icon="@drawable/ic_share"
android:title="Chia sẻ" />
<item
android:id="@+id/nav_send"
android:icon="@drawable/ic_send"
android:title="Gửi" />
</group>
<item android:title="Cài đặt">
<menu>
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_settings"
android:title="Cài đặt" />
</menu>
</item>
</menu>
Bước 6: Navigation Graph (res/navigation/mobile_navigation.xml)
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="app.com.sample.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/nav_gallery"
android:name="app.com.sample.ui.gallery.GalleryFragment"
android:label="@string/menu_gallery"
tools:layout="@layout/fragment_gallery" />
<fragment
android:id="@+id/nav_slideshow"
android:name="app.com.sample.ui.slideshow.SlideshowFragment"
android:label="@string/menu_slideshow"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/nav_tools"
android:name="app.com.sample.ui.tools.ToolsFragment"
android:label="@string/menu_tools"
tools:layout="@layout/fragment_tools" />
<fragment
android:id="@+id/nav_share"
android:name="app.com.sample.ui.share.ShareFragment"
android:label="@string/menu_share"
tools:layout="@layout/fragment_share" />
<fragment
android:id="@+id/nav_send"
android:name="app.com.sample.ui.send.SendFragment"
android:label="@string/menu_send"
tools:layout="@layout/fragment_send" />
</navigation>
Bước 7: Fragment mẫu (HomeFragment.java)
package app.com.sample.ui.home;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
TextView textView = root.findViewById(R.id.text_home);
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
return root;
}
}
// HomeViewModel.java
package app.com.sample.ui.home;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class HomeViewModel extends ViewModel {
private final MutableLiveData<String> text = new MutableLiveData<>();
public HomeViewModel() {
text.setValue("Chào mừng đến với Trang chủ!");
}
public LiveData<String> getText() {
return text;
}
}
<!-- fragment_home.xml -->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Bước 8: MainActivity (Điều phối Navigation)
package app.com.sample;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.navigation.NavigationView;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(view -> Snackbar.make(view, "Thay bằng hành động của bạn", Snackbar.LENGTH_LONG)
.setAction("Action", null).show());
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Cấu hình các destination top-level (hiện hamburger icon)
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
R.id.nav_tools, R.id.nav_share, R.id.nav_send)
.setOpenableLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
Bước 9: Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. Vuốt từ cạnh trái hoặc nhấn icon hamburger → mở drawer → click item → chuyển Fragment.

Tóm tắt luồng hoạt động
DrawerLayoutchứa 2 child: Content (AppBar + NavHostFragment) + NavigationViewNavigationViewlấy menu từapp:menu, header từapp:headerLayoutNavHostFragmentnạpnavGraphđịnh nghĩa các destination (Fragment)NavigationUI.setupWithNavController()tự động đồng bộ click menu ↔ navigateAppBarConfigurationquyết định icon toolbar: hamburger (top-level) hoặc back arrow (nested)
Lưu ý
- Template "Navigation Drawer Activity" của Android Studio tạo sẵn toàn bộ cấu trúc này
- Mỗi item menu
android:idphải khớp vớiandroid:idtrong navigation graph - Dùng
NavControllerđể navigate programmatically:navController.navigate(R.id.nav_gallery) - Deep link: Thêm
<deepLink app:uri="..." />trong navigation graph