কম্পিউটার টিউটোরিয়াল

Android-এ কাস্টম নেভিগেশন ড্রয়ার তৈরি করার পদ্ধতি

Material Design Navigation Drawer বাস্তবায়ন

এই টিউটোরিয়ালে দেখানো হয়েছে কীভাবে DrawerLayout, NavigationView, এবং ActionBarDrawerToggle ব্যবহার করে একটি পূর্ণাঙ্গ নেভিগেশন ড্রয়ার (সাইড মেনু) তৈরি করা যায়। মডার্ন Android-এ NavigationView মেনু রিসোর্স থেকে অটোমেটিক্যালি আইটেম বানাতে পারে।

আর্কিটেকচার

  • DrawerLayout — রুট ভিউ গ্রুপ, দুটি চাইল্ড: প্রধান কন্টেন্ট + নেভিগেশন ভিউ
  • NavigationView — মেনু আইটেম, হেডার, ফুটার ধারণ করে
  • AppBarLayout + Toolbar — টুলবার, হ্যামবার্গার আইকন, টাইটেল
  • ActionBarDrawerToggle — হ্যামবার্গার ↔ ব্যাক অ্যানিমেশন, ড্র্যাওয়ার সিঙ্ক

ধাপ ১: প্রজেক্ট সেটআপ (Material Components Theme)

build.gradle (app) — Material Components লাইব্রেরি নিশ্চিত করুন:

dependencies {
    implementation "com.google.android.material:material:1.11.0"
    implementation "androidx.appcompat:appcompat:1.6.1"
    implementation "androidx.constraintlayout:constraintlayout:2.1.4"
    implementation "androidx.drawerlayout:drawerlayout:1.2.0"
}

themes.xml (values/themes.xml) — NoActionBar থিম ব্যবহার করুন:

<style name="Theme.CustomNavDrawer" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorPrimaryVariant">@color/purple_700</item>
    <item name="colorOnPrimary">@color/white</item>
    <item name="colorSecondary">@color/teal_200</item>
    <item name="colorOnSecondary">@color/black</item>
</style>

ধাপ ২: মেনু রিসোর্স (res/menu/nav_drawer_menu.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="হোম" />
        <item
            android:id="@+id/nav_profile"
            android:icon="@drawable/ic_person"
            android:title="প্রোফাইল" />
        <item
            android:id="@+id/nav_settings"
            android:icon="@drawable/ic_settings"
            android:title="সেটিংস" />
        <item
            android:id="@+id/nav_messages"
            android:icon="@drawable/ic_message"
            android:title="মেসেজ" />
    </group>

    <item android:title="অন্যান্য">
        <menu>
            <item
                android:id="@+id/nav_share"
                android:icon="@drawable/ic_share"
                android:title="শেয়ার করুন" />
            <item
                android:id="@+id/nav_about"
                android:icon="@drawable/ic_info"
                android:title="অ্যাপ সম্পর্কে" />
            <item
                android:id="@+id/nav_logout"
                android:icon="@drawable/ic_logout"
                android:title="লগ আউট" />
        </menu>
    </item>
</menu>

ধাপ ৩: হেডার লেআউট (res/layout/nav_header_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@dimen/nav_header_height"
    android:background="@drawable/side_nav_bar"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.MaterialComponents.Dark">

    <ImageView
        android:id="@+id/ivAvatar"
        android:layout_width="@dimen/nav_header_avatar_size"
        android:layout_height="@dimen/nav_header_avatar_size"
        android:contentDescription="@string/nav_header_desc"
        android:scaleType="centerCrop"
        app:srcCompat="@mipmap/ic_launcher_round" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/nav_header_vertical_spacing"
        android:text="@string/nav_header_title"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" />

    <TextView
        android:id="@+id/tvEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/nav_header_subtitle" />

</LinearLayout>

ধাপ ৪: ডিমেনশন (res/values/dimens.xml)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="nav_header_height">176dp</dimen>
    <dimen name="nav_header_avatar_size">64dp</dimen>
    <dimen name="nav_header_vertical_spacing">8dp</dimen>
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
</resources>

ধাপ ৫: প্রধান লেআউট (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">

    <!-- প্রধান কন্টেন্ট -->
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- নেভিগেশন ড্রয়ার (লেফট/স্টার্ট) -->
    <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/nav_drawer_menu"
        app:itemTextAppearance="@style/TextAppearance.MaterialComponents.Body1"
        app:itemIconTint="?attr/colorOnSurface"
        app:itemTextColor="?attr/colorOnSurface" />

</androidx.drawerlayout.widget.DrawerLayout>

ধাপ ৬: 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"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.CustomNavDrawer.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/Theme.CustomNavDrawer.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <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="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

ধাপ ৭: Content Layout (res/layout/content_main.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"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/app_bar_main">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="নেভিগেশন ড্রয়ার ডেমো"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="হ্যামবার্গার আইকনে ট্যাপ করুন বা বাম প্রান্ত থেকে ড্র্যাগ করুন"
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

ধাপ ৮: MainActivity.java

package com.example.customnavdrawer;

import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
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.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;

public class MainActivity extends AppCompatActivity 
        implements NavigationView.OnNavigationItemSelectedListener {

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Views
        drawerLayout = findViewById(R.id.drawer_layout);
        navigationView = findViewById(R.id.nav_view);
        toolbar = findViewById(R.id.toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);

        // Toolbar সেট আপ
        setSupportActionBar(toolbar);

        // FAB ক্লিক
        fab.setOnClickListener(view -> 
            Snackbar.make(view, "আপনার অ্যাকশন দিন", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show()
        );

        // Drawer Toggle (হ্যামবার্গার ↔ ব্যাক অ্যানিমেশন)
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawerLayout, toolbar,
                R.string.navigation_drawer_open,
                R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        // Navigation Item Click Listener
        navigationView.setNavigationItemSelectedListener(this);

        // ডিফল্ট সিলেকশন (ঐচ্ছিক)
        navigationView.setCheckedItem(R.id.nav_home);
    }

    @Override
    public void onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.nav_home) {
            // হোম ফ্র্যাগমেন্ট/এক্টিভিটি লোড
            showToast("হোম সিলেক্টেড");
        } else if (id == R.id.nav_profile) {
            showToast("প্রোফাইল সিলেক্টেড");
        } else if (id == R.id.nav_settings) {
            showToast("সেটিংস সিলেক্টেড");
        } else if (id == R.id.nav_messages) {
            showToast("মেসেজ সিলেক্টেড");
        } else if (id == R.id.nav_share) {
            shareApp();
        } else if (id == R.id.nav_about) {
            showToast("অ্যাপ সম্পর্কে");
        } else if (id == R.id.nav_logout) {
            logout();
        }

        // ড্র্যাওয়ার বন্ধ করুন
        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }

    private void showToast(String msg) {
        android.widget.Toast.makeText(this, msg, android.widget.Toast.LENGTH_SHORT).show();
    }

    private void shareApp() {
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_SUBJECT, "এই অ্যাপটি দেখুন");
        shareIntent.putExtra(Intent.EXTRA_TEXT, "https://play.google.com/store/apps/details?id=" + getPackageName());
        startActivity(Intent.createChooser(shareIntent, "শেয়ার করুন"));
    }

    private void logout() {
        // লগআউট লজিক
        showToast("লগ আউট হয়েছে");
    }
}

ধাপ ৯: strings.xml (res/values/strings.xml)

<resources>
    <string name="app_name">Custom Nav Drawer</string>
    <string name="navigation_drawer_open">মেনু খুলুন</string>
    <string name="navigation_drawer_close">মেনু বন্ধ করুন</string>
    <string name="nav_header_desc">প্রোফাইল ছবি</string>
    <string name="nav_header_title">ব্যবহারকারীর নাম</string>
    <string name="nav_header_subtitle">user@example.com</string>
</resources>

ধাপ ১০: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.customnavdrawer">

    <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/Theme.CustomNavDrawer">

    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:theme="@style/Theme.CustomNavDrawer">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    </application>
</manifest>

কাস্টমাইজেশন টিপস

কাস্টমাইজেশনকীভাবে
হেডারে ডাইনামিক ডেটা (নাম, ইমেইল)navigationView.getHeaderView(0).findViewById(R.id.tvEmail).setText(...)
মেনু আইটেম ডাইনামিকলি আপডেটnavigationView.getMenu().findItem(R.id.nav_xxx).setVisible(false)
ব্যাজ আইকন/ব্যাজ কাউন্টMenuItemCompat.setActionView() বা NotificationCompat.BadgeDrawable
ড্র্যাওয়ার লক মোডdrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
Right/End ড্রয়ার (RTL)android:layout_gravity="end", GravityCompat.END

আধুনিক বিকল্প: Navigation Component (Jetpack)

বড় অ্যাপের জন্য androidx.navigation:navigation-fragment + navigation-ui ব্যবহার করুন। এটি ফ্র্যাগমেন্ট নেভিগেশন, ডিপ লিংক, সেফ আর্গস, এবং ড্র্যাওয়ার ইন্টিগ্রেশন অটোমেটিক হ্যান্ডেল করে।

পরীক্ষা চেকলিস্ট

  1. অ্যাপ চালু করুন → টুলবারে হ্যামবার্গার আইকন দেখুন
  2. হ্যামবার্গারে ট্যাপ করুন → ড্র্যাওয়ার স্লাইড করে আসবে
  3. বাম প্রান্ত থেকে ড্র্যাগ করুন → ড্র্যাওয়ার খুলবে
  4. মেনু আইটেমে ক্লিক করুন → টোস্ট/অ্যাকশন হবে, ড্র্যাওয়ার বন্ধ হবে
  5. ব্যাক বাটন চাপুন → ড্র্যাওয়ার বন্ধ হবে (যদি খোলা থাকে)
  6. রোটেশন (ল্যান্ডস্কেপ) এ ড্র্যাওয়ার সঠিক কাজ করছে কিনা
  1. অ্যান্ড্রয়েডে ActionBar-এ কাস্টম ভিউ দেখানোর পদ্ধতি

  2. অ্যান্ড্রয়েড অ্যাপে TextToSpeech তৈরি করার পদ্ধতি

  3. Facebook-এ Android অ্যাপ তৈরি করার পদ্ধতি

  4. অ্যান্ড্রয়েডে কাস্টম নোটিফিকেশন লেআউট ও টেক্সট কালার তৈরি করা