AlertDialog.Builder dialog = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View v = inflater.inflate(R.layout.diy, null);
dialog.setView(v);
dialog.setPositiveButton("確定", (dialog, which) -> {
// 錯誤:在 Activity 中查找,但 EditText 在 Dialog 視圖中
EditText editText = (EditText) findViewById(R.id.editText1);
String text = editText.getText().toString(); // NPE
});
Activity.findViewById() 只搜索 Activity 的內容視圖 (setContentView 設置的佈局),不包含 Dialog 的獨立視圖層級。
dialog.setPositiveButton("確定", (dialog, which) -> {
// ✅ 正確:在 Dialog 的視圖 v 中查找
EditText editText = v.findViewById(R.id.editText1);
String text = editText.getText().toString();
Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
});
public void showInputDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("輸入標題");
// 1. 獲取佈局填充器
LayoutInflater inflater = LayoutInflater.from(this);
// 2. 填充 Dialog 專用佈局
View dialogView = inflater.inflate(R.layout.dialog_input, null);
// 3. 預先查找控件(避免在 listener 中重複查找)
final EditText inputEditText = dialogView.findViewById(R.id.et_input);
// 4. 設置視圖
builder.setView(dialogView);
// 5. 設置按鈕
builder.setPositiveButton("確定", (dialog, which) -> {
String text = inputEditText.getText().toString().trim();
if (!text.isEmpty()) {
onInputConfirmed(text);
}
});
builder.setNegativeButton("取消", null);
// 6. 顯示
builder.show();
}
private void onInputConfirmed(String text) {
// 業務邏輯
}
<?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="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入內容"
android:inputType="text" />
</LinearLayout>
DialogFragment 替代 AlertDialog 處理生命週期setError() 顯示錯誤提示dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)