Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Tạo SlidingDrawer trượt từ bên trái trên Android

Giới thiệu

Bài viết này hướng dẫn cách tạo SlidingDrawer trượt từ bên trái (left) trên Android. Lưu ý: SlidingDrawer đã deprecated từ API 17 (Android 4.2) và không được khuyến khích dùng trong ứng dụng hiện đại. Nên sử dụng DrawerLayout (Navigation Drawer) hoặc BottomSheet thay thế.

Các bước thực hiện (Chỉ để tham khảo/hiểu code cũ)

Bước 1: Tạo dự án mới

Mở Android Studio, chọn File → New Project và điền thông tin cần thiết.

Bước 2: Layout sử dụng SlidingDrawer (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="4dp"
    tools:context=".MainActivity">

    <SlidingDrawer
        android:id="@+id/slidingDrawer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:handle="@+id/handler"
        android:content="@+id/content"
        android:rotation="180">

        <!-- Handle (nút kéo) -->
        <ImageView
            android:id="@+id/handler"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_arrow_upward_black_24dp"
            android:rotation="270" />

        <!-- Content (nội dung trượt ra) -->
        <LinearLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:rotation="180">

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/image" />

        </LinearLayout>

    </SlidingDrawer>

</LinearLayout>

Bước 3: Activity (src/MainActivity.java)

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // SlidingDrawer hoạt động hoàn toàn qua XML, không cần code Java
    }
}

Bước 4: Manifest (androidManifest.xml)

<?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">
            <intent-filter>
                
                
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Kéo handle (mũi tên) để trượt drawer từ trái sang.

⚠️ Lưu ý quan trọng: SlidingDrawer đã DEPRECATED

Không sử dụng SlidingDrawer trong ứng dụng mới. Lý do:

  • Deprecated từ API 17 (Android 4.2 Jelly Bean).
  • Không được cập nhật, sửa lỗi, hỗ trợ Material Design.
  • Hành vi không nhất quán trên các phiên bản Android/OEM khác nhau.
  • Không hỗ trợ gesture navigation, edge-to-edge display.
  • Có thể bị remove trong tương lai.

Thay thế hiện đại: DrawerLayout (Navigation Drawer)

DrawerLayout là thành phần chuẩn của Material Design, hỗ trợ drawer từ trái, phải, bottom, lock mode, scrim, v.v.

Dependency

implementation 'androidx.drawerlayout:drawerlayout:1.2.0'
implementation 'com.google.android.material:material:1.12.0'

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/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <!-- Main content -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="Main Content"
            android:textSize="24sp" />

    </LinearLayout>

    <!-- Navigation Drawer (từ trái - START) -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer_menu" />

</androidx.drawerlayout.widget.DrawerLayout>

Menu drawer (res/menu/drawer_menu.xml)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="https://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/nav_home" android:title="Trang chủ" android:icon="@drawable/ic_home" />
        <item android:id="@+id/nav_profile" android:title="Hồ sơ" android:icon="@drawable/ic_person" />
        <item android:id="@+id/nav_settings" android:title="Cài đặt" android:icon="@drawable/ic_settings" />
    </group>
</menu>

Activity code

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;

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

        drawerLayout = findViewById(R.id.drawerLayout);
        navigationView = findViewById(R.id.navigationView);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Hamburger icon + animation
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawerLayout, toolbar, 
            R.string.open_drawer, R.string.close_drawer
        );
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        // Xử lý click menu
        navigationView.setNavigationItemSelectedListener(item -> {
            int id = item.getItemId();
            if (id == R.id.nav_home) {
                // Handle home
            } else if (id == R.id.nav_profile) {
                // Handle profile
            } else if (id == R.id.nav_settings) {
                // Handle settings
            }
            drawerLayout.closeDrawer(GravityCompat.START);
            return true;
        });
    }

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

So sánh

Đặc điểm SlidingDrawer (Deprecated) DrawerLayout (Standard)
API Level Deprecated API 17+ API 4+ (AndroidX)
Material Design ❌ Không ✅ Hỗ trợ đầy đủ
Gesture navigation ❌ Không ✅ Tích hợp Edge-to-edge
Vị trí Trái, phải, trên, dưới (xoay rotation) Start (trái), End (phải), Bottom
Animation Cơ bản Mượt, spring, scrim
Lock mode ❌ ✅ (LOCK_MODE_LOCKED_CLOSED, UNLOCKED...)

Kết luận

Chỉ tìm hiểu SlidingDrawer để maintain code cũ. Mọi dự án mới hãy dùng DrawerLayout + NavigationView hoặc BottomSheetDialogFragment (cho bottom sheet).