@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
et1 = (EditText) findViewById(R.id.editText1); // 1. 先 findViewById
et2 = (EditText) findViewById(R.id.editText2);
bt = (Button) findViewById(R.id.button1);
setContentView(R.layout.activity_main); // 2. 再 setContentView → 所有 findViewById 返回 null
// ...
}
setContentView() 完成佈局填充,構建 View 層級結構。在此之前調用 findViewById(),Activity 的 mContentView 為 null,故返回 null。後續對 et1、bt 等操作(如 setOnClickListener)觸發 NullPointerException。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 1. 先填充佈局
et1 = (EditText) findViewById(R.id.editText1); // 2. 再查找 View
et2 = (EditText) findViewById(R.id.editText2);
bt = (Button) findViewById(R.id.button1);
// 後續邏輯...
}
TabActivity 自 API 13 (Android 3.2) 起棄用,現代應用使用 ViewPager + Fragment + TabLayout 實現分頁。TabLayout + ViewPager2。FragmentStateAdapter 管理分頁 Fragment。TabLayoutMediator 綁定 TabLayout 與 ViewPager2。| 錯誤 | 後果 | 修正 |
|---|---|---|
| findViewById 在 setContentView 前 | NPE | 調整順序 |
| 使用棄用 TabActivity | 兼容性風險、功能受限 | 遷移 ViewPager2+Fragment |
| ListView/Spinner 適配器未設置 | 空列表 | setAdapter() |
| AlertDialog 按鈕邏輯錯誤 | 點擊無反應 | 使用 setButton(DialogInterface.OnClickListener) |
養成「先 setContentView,後 findViewById」肌肉記憶,並拥抱現代 Android 架構組件。