Android Activity调用recreate后ViewPager2内Fragment高度异常求解
可行方案(均基于系统标准API,代码量极少)
方案1:禁用ViewPager2自动状态恢复,手动保存选中位置
这个方案直接切断重建后ViewPager2复用旧测量缓存的路径,完全适配不同高度的Fragment:
- 给布局中ViewPager2添加
android:saveEnabled="false"属性,阻止系统自动恢复ViewPager2的测量相关缓存状态:
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/calibrate_steps_pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:layout_gravity="center" android:layout_margin="10dp" android:saveEnabled="false" />
- 在Activity中手动保存和恢复ViewPager2的选中页码:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // 手动保存当前选中页 outState.putInt("KEY_PAGER_SELECTED_POS", viewPager.currentItem) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 原有初始化逻辑:加载布局、初始化适配器、绑定TabLayout等 // ... // 恢复选中页 val selectedPos = savedInstanceState?.getInt("KEY_PAGER_SELECTED_POS") ?: 0 viewPager.setCurrentItem(selectedPos, false) }
方案2:添加页面切换重测量逻辑(无需修改状态保存逻辑)
如果不想禁用ViewPager2的默认状态恢复,只需要添加页面切换回调,每次切换页面时触发重新测量即可:
// 初始化ViewPager2后添加回调 viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) viewPager.requestLayout() } })
额外布局修正
当前布局存在错误:垂直方向的LinearLayout中,TabLayout的android:layout_height设置为match_parent会抢占所有高度,导致ViewPager2的测量逻辑异常,需要改为wrap_content:
<com.google.android.material.tabs.TabLayout android:id="@+id/calibrate_steps_tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" app:tabBackground="@drawable/tab_indicator_selector" app:tabGravity="center" app:tabIndicatorHeight="0dp" />
以上方案均无需修改原有重建逻辑,可继续使用recreate()方法保持回退栈位置,总代码量不超过20行。
内容的提问来源于stack exchange,提问作者RomanKovalev
相关产品推荐
相关产品推荐

