首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android DrawerLayout + ListView 鎖屏/虛擬鍵盤顯示導致空指針:生命週期與配置變更處理

     編輯:程式設計疑難解答

現象:鎖屏、顯示/隱藏虛擬導航列 → ListView Adapter getView 空指針

側滑選單 DrawerLayout + ListView,主介面 ViewPager。鎖屏或導航列變化觸發 Activity 重建或配置變更,導致 Adapter 內部列表變 null。

根本原因

  1. 配置變更(螢幕尺寸、密度、鍵盤狀態)預設銷毀重建 Activity。
  2. 重建時 onCreate 重新初始化,若資料載入為非同步,ListView 可能先於資料就緒被繪製。
  3. getView 中 list.get(position) 為 null → NullPointerException。

解決方案

方案一:ViewModel + LiveData 保留資料(現代架構,推薦)


public class MyViewModel extends ViewModel {
    public MutableLiveData> items = new MutableLiveData<>();
    // 載入資料邏輯...
}

// Activity
viewModel.items.observe(this, list -> {
    adapter.setData(list); // 安全更新,list 不為 null
    adapter.notifyDataSetChanged();
});

方案二:onSaveInstanceState 保存列表資料


@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);
}

方案三:android:configChanges 防止重建(輕量但有限制)



配合 onConfigurationChanged 手動處理佈局調整。**注意**:API 24+ 多窗口模式下部分配置變更仍會重建。

方案四:Adapter 防禦性編程


@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 庫做法

  • 成熟庫(如 SlidingMenu、NavigationView)內部使用 RecyclerView + ViewModel 或在 onDetachedFromWindow 釋放資源,避免配置變更時存取已銷毀的列表。
  • 建議遷移至 NavigationView + RecyclerView + ViewModel,棄用 ListView + DrawerLayout 手動實現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved