การสร้าง Dialog แบบกำหนดเอง (Custom Dialog) ด้วย AlertDialog และ Layout XML
ตัวอย่างนี้แสดงวิธีสร้าง Dialog ที่มี Layout เอง (Custom Layout) ประกอบด้วย EditText และปุ่ม OK/Cancel เพื่อรับข้อความจากผู้ใช้
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project → กรอกรายละเอียด → Finish
ขั้นตอนที่ 2: Layout หลัก - res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/myCustomMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ข้อความที่ปรับแต่งได้"
android:textSize="22sp"
android:textAlignment="center"
android:layout_marginTop="30dp" />
<Button
android:layout_width="140dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:text="แสดงข้อความ"
android:backgroundTint="@color/colorPrimary"
android:textSize="20dp"
android:textColor="#FFFFFF"
android:onClick="btn_showMessage" />
</RelativeLayout>
ขั้นตอนที่ 3: สร้าง Custom Dialog Layout
คลิกขวาที่ res/layout → New → Layout Resource File → ชื่อ: custom_dialog → Root: LinearLayout
res/layout/custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ป้อนข้อความของคุณ"
android:textSize="22sp"
android:textAlignment="center" />
<EditText
android:id="@+id/txt_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="ป้อนข้อความ"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<Button
android:id="@+id/btn_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/colorPrimary"
android:text="ยกเลิก"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<Button
android:id="@+id/btn_okay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/colorPrimary"
android:text="ตกลง"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
ขั้นตอนที่ 4: MainActivity.java
package app.com.sample;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
TextView myCustomMessage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myCustomMessage = findViewById(R.id.myCustomMessage);
}
public void btn_showMessage(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
View dialogView = getLayoutInflater().inflate(R.layout.custom_dialog, null);
EditText txtInput = dialogView.findViewById(R.id.txt_input);
Button btnCancel = dialogView.findViewById(R.id.btn_cancel);
Button btnOkay = dialogView.findViewById(R.id.btn_okay);
builder.setView(dialogView);
AlertDialog alertDialog = builder.create();
alertDialog.setCanceledOnTouchOutside(false);
btnCancel.setOnClickListener(v -> alertDialog.dismiss());
btnOkay.setOnClickListener(v -> {
myCustomMessage.setText(txtInput.getText().toString());
alertDialog.dismiss();
});
alertDialog.show();
}
}
ขั้นตอนที่ 5: 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>
วิธีสร้าง Dialog แบบอื่นๆ
1. DialogFragment (แนะนำสำหรับ Lifecycle)
public class CustomDialogFragment extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getLayoutInflater().inflate(R.layout.custom_dialog, null);
builder.setView(view);
// setup views...
return builder.create();
}
}
// ใช้งาน
new CustomDialogFragment().show(getSupportFragmentManager(), "custom_dialog");
2. BottomSheetDialog (Material Design)
BottomSheetDialog dialog = new BottomSheetDialog(this); View view = getLayoutInflater().inflate(R.layout.custom_dialog, null); dialog.setContentView(view); dialog.show();
3. MaterialAlertDialogBuilder (Material Components)
new MaterialAlertDialogBuilder(this)
.setView(dialogView)
.setPositiveButton("ตกลง", (dialog, which) -> { ... })
.setNegativeButton("ยกเลิก", (dialog, which) -> dialog.dismiss())
.show();
⚠️ ข้อควรระวัง
- ใช้
getLayoutInflater().inflate()ไม่ใช่ LayoutInflater.from() เพื่อให้ Theme ถูกต้อง - Dialog ต้อง dismiss() เมื่อไม่ใช้แล้ว เพื่อหลีกเลี่ยง Memory Leak
- setCanceledOnTouchOutside(false) ป้องกันปิดโดยการแตะนอกพื้นที่
- สำหรับ Fragment ให้ใช้ getChildFragmentManager()