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

Android ViewPager 旋轉螢幕重置頁面問題與狀態保存方案

     編輯:程式設計綜合問答

ViewPager 內含 WebView 等複雜視圖時,螢幕旋轉觸發 Activity 重建,導致 ViewPager 重置至第 0 頁。需結合 onSaveInstanceState、Fragment.setRetainInstance(已棄用)、ViewModel 或 configChanges 保存當前頁面索引與片段狀態。

方案一:ViewModel 保存頁面索引(現代推薦)


class PagerViewModel : ViewModel() {
    var currentPage = 0
        private set
    
    fun setCurrentPage(page: Int) {
        currentPage = page
    }
}

// Activity/Fragment
val viewModel = ViewModelProvider(this).get(PagerViewModel::class.java)

viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageSelected(position: Int) {
        viewModel.setCurrentPage(position)
    }
})

// 恢復
viewPager.post { viewPager.setCurrentItem(viewModel.currentPage, false) }

方案二:onSaveInstanceState 手動保存(傳統)


private static final String KEY_CURRENT_PAGE = "current_page";

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(KEY_CURRENT_PAGE, viewPager.getCurrentItem());
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    int page = savedInstanceState.getInt(KEY_CURRENT_PAGE, 0);
    viewPager.post(() -> viewPager.setCurrentItem(page, false));
}

方案三:FragmentStateAdapter + setRetainInstance(舊版 FragmentPagerAdapter)


// Fragment 內
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true); // 保留 Fragment 實例,但 View 仍會重建
}

// ViewPager 使用 FragmentStatePagerAdapter(而非 FragmentPagerAdapter)
// FragmentStatePagerAdapter 會銷毀不可见 Fragment 的 View,保留實例

注意:setRetainInstance 在 Fragment 1.3.0+ 棄用,改用 ViewModel。

方案四:configChanges 自行處理旋轉(適用 WebView 重載昂貴場景)


<activity
    android:name=".PagerActivity"
    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
</activity>

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // ViewPager、WebView 實例保留,無需重載
    // 若需切換佈局,手動調用 viewPager.setAdapter(...) 或調整參數
}

WebView 特別處理:避免旋轉重載網頁


// 方案 A:configChanges(最簡單)
// 方案 B:儲存/恢復 WebView 狀態
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    webView.saveState(outState); // 儲存歷史、捲動位置、表單資料
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    webView.restoreState(savedInstanceState);
}

方案選擇指南

場景推薦方案理由
一般 ViewPager + 簡單 FragmentViewModel + onSaveInstanceState架構清晰、支援進程死後恢復
ViewPager + WebView(重載慢)configChanges + WebView.saveState避免重建開銷、保留網頁狀態
複雜巢狀 FragmentViewModel + FragmentStateAdapter生命週期自動管理

理解 Activity 重建機制並選擇適當策略,能讓 ViewPager 在旋轉、多視窗、折疊螢幕等場景下保持流暢體驗。

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