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

Cách tắt Dialog khi nhấn ra ngoài vùng Dialog trong Android

Giới thiệu

Bài viết này minh họa cách cho phép người dùng đóng AlertDialog bằng cách nhấn ra ngoài vùng dialog (outside touch). Chỉ cần gọi setCanceledOnTouchOutside(true) trên đối tượng AlertDialog.

Các bước thực hiện

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

Mở Android Studio, chọn File → New Project và tạo dự án.

Bước 2: Thiết kế giao diện (res/layout/activity_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="match_parent"
    android:gravity="center">

    <TextView
        android:id="@+id/click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Nhấn để mở Dialog"
        android:textSize="30sp" />

</LinearLayout>

Bước 3: Viết code logic (src/MainActivity.java)

import android.annotation.TargetApi;
import android.content.DialogInterface;
import android.os.Build;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    TextView text;

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

        text = findViewById(R.id.click);
        text.setOnClickListener(v -> showAlertBox());
    }

    private void showAlertBox() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Dialog Title");
        builder.setMessage("Bạn muốn đóng dialog này không?");

        builder.setPositiveButton("Có", (dialog, which) ->
            Toast.makeText(this, "Đã nhấn Có", Toast.LENGTH_LONG).show()
        );

        builder.setNegativeButton("Không", (dialog, which) -> {
            // Không làm gì, dialog tự đóng
        });

        AlertDialog alert = builder.create();
        // QUAN TRỌNG: Cho phép tắt dialog khi nhấn ra ngoài
        alert.setCanceledOnTouchOutside(true);
        alert.show();
    }
}

Bước 4: Cấu hình 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>
                <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. Nhấn TextView để mở dialog, sau đó nhấn ra ngoài vùng dialog -> dialog tự đóng mà không cần nhấn nút.

Các phương thức liên quan

Phương thứcChức năng
setCanceledOnTouchOutside(true)Cho phép đóng khi nhấn ra ngoài (mặc định: true cho AlertDialog)
setCancelable(false)Vô hiệu hóa phím Back và nhấn ra ngoài (dialog bắt buộc chọn nút)
setOnCancelListener()Lắng nghe khi dialog bị hủy (bấm Back hoặc outside)
setOnDismissListener()Lắng nghe khi dialog đóng (bất kỳ lý do nào)

Tùy chỉnh Dialog nâng cao

// Dialog tùy chỉnh layout
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.custom_dialog);
dialog.setCanceledOnTouchOutside(true);
// Hoặc dùng DialogFragment (khuyến nghị cho lifecycle phức tạp)

Lưu ý

  • Mặc định AlertDialog đã có setCanceledOnTouchOutside(true), dòng code trên chủ yếu để minh họa
  • Nếu dùng Dialog thuần (không phải AlertDialog), mặc định là false – cần bật thủ công
  • Khi setCancelable(false), cả Back và outside touch đều bị chặn