在 Dialog 中使用 findViewById(R.id.list) 直接呼叫 Activity 的方法,會在 Activity 佈局中尋找 ID 為 list 的視圖,而非 Dialog 佈局,導致回傳 null。修正:對 Dialog 實例呼叫 findViewById。
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.tone_dialog);
// 錯誤:在 Activity 尋找
ListView toneList = (ListView) findViewById(R.id.list); // 回傳 null
// 後續 toneList.setAdapter(...) 拋出 NPE
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.tone_dialog);
// 正確:在 Dialog 佈局中尋找
ListView toneList = (ListView) dialog.findViewById(R.id.list);
toneList.setAdapter(adapter);
dialog.show();
public void showToneDialog() {
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.tone_dialog);
dialog.setTitle(R.string.tonePromptTitle);
// 關鍵:dialog.findViewById
ListView toneList = dialog.findViewById(R.id.list);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.tones, android.R.layout.simple_list_item_1);
toneList.setAdapter(adapter);
toneList.setOnItemClickListener((parent, view, position, id) -> {
String selectedTone = (String) parent.getItemAtPosition(position);
// 處理選擇
dialog.dismiss();
});
dialog.show();
}
new AlertDialog.Builder(this)
.setTitle(R.string.tonePromptTitle)
.setAdapter(ArrayAdapter.createFromResource(this, R.array.tones, android.R.layout.simple_list_item_1),
(dialog, which) -> {
String selectedTone = getResources().getStringArray(R.array.tones)[which];
// 處理選擇
})
.show();
視圖尋找作用域必須與視圖所屬容器一致
Activity 佈局用Activity.findViewById、Dialog 佈局用Dialog.findViewById、Fragment 佈局用View.findViewById(在 onCreateView 返回的根視圖上)。
LayoutInflater.inflate 返回的 View 上找子視圖 → 正確Fragment.onCreateView 中用 getActivity().findViewById → 錯誤(應用 view.findViewById)RecyclerView.ViewHolder 建構子中用 itemView.findViewById → 正確牢記「誰持有佈局,誰負責 findViewById」,即可徹底避免此類空指針問題。