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ức | Chứ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
Dialogthuầ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