側滑選單 DrawerLayout + ListView,主介面 ViewPager。鎖屏或導航列變化觸發 Activity 重建或配置變更,導致 Adapter 內部列表變 null。
onCreate 重新初始化,若資料載入為非同步,ListView 可能先於資料就緒被繪製。getView 中 list.get(position) 為 null → NullPointerException。
public class MyViewModel extends ViewModel {
public MutableLiveData> items = new MutableLiveData<>();
// 載入資料邏輯...
}
// Activity
viewModel.items.observe(this, list -> {
adapter.setData(list); // 安全更新,list 不為 null
adapter.notifyDataSetChanged();
});
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("list_data", new ArrayList<>(dataList));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
dataList = savedInstanceState.getParcelableArrayList("list_data");
}
// 初始化 Adapter
adapter = new MyAdapter(this, dataList != null ? dataList : new ArrayList<>());
listView.setAdapter(adapter);
}
配合 onConfigurationChanged 手動處理佈局調整。**注意**:API 24+ 多窗口模式下部分配置變更仍會重建。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (dataList == null || position >= dataList.size()) {
return new TextView(context); // 或返回空 View,避免崩潰
}
Item item = dataList.get(position);
// 正常綁定...
}
SlidingMenu、NavigationView)內部使用 RecyclerView + ViewModel 或在 onDetachedFromWindow 釋放資源,避免配置變更時存取已銷毀的列表。ListView + DrawerLayout 手動實現。