View view = View.inflate(this, R.layout.user_dialog, null);
final EditText userName = (EditText) findViewById(R.id.edit_text_name); // 錯誤:在 Activity 找
final EditText passWord = (EditText) findViewById(R.id.edit_text_password);
崩潰:NullPointerException 於 userName.getText(),因 userName 為 null。
findViewById 是 Activity/View 的方法。調用 Activity.findViewById 只會在 Activity 的內容視圖 中查找,而 user_dialog.xml 的控件在 view 這個獨立視圖樹中。
View view = View.inflate(this, R.layout.user_dialog, null);
// 必須在 inflate 返回的 view 上調用 findViewById
final EditText userName = (EditText) view.findViewById(R.id.edit_text_name);
final EditText passWord = (EditText) view.findViewById(R.id.edit_text_password);
new AlertDialog.Builder(this)
.setView(view)
.setPositiveButton("取消", null)
.setNegativeButton("確定", (dialog, which) -> {
String strUserName = userName.getText().toString();
String strPassWord = passWord.getText().toString();
Toast.makeText(this, strUserName + " : " + strPassWord, Toast.LENGTH_SHORT).show();
})
.show();
現代 Android 開發推薦使用 DialogFragment 管理對話框生命周期,避免內存洩漏:
public class UserDialogFragment extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.user_dialog, null);
EditText userName = view.findViewById(R.id.edit_text_name);
EditText passWord = view.findViewById(R.id.edit_text_password);
return new AlertDialog.Builder(getContext())
.setView(view)
.setPositiveButton("取消", null)
.setNegativeButton("確定", (d, w) -> {
// 通過接口回調傳遞數據
})
.create();
}
}