FragmentStateAdapter管理fragment
问题:一个viewpager2使用了FragmentStateAdapter,当系统配置发生变化(切换横竖屏、切换深色模式、切换语言),会多出fragment实例,每切一次就会多一次。查看日志每次切换后获取fragment的时候,都会重新走FragmentStateAdapter的createFragment。而之前已经生成的fragment都会重建。所以造成上面的现象和问题。
原因:这个viewpager2是动态通过代码new创建的,改成直接写在xml布局中就正常了(一般写在xml中都会加一个id的)
根因:只有绑定id的viewpager2才能正常同步fragment。从xml加载的也需要加id才能。代码动态创建的,设置id后也能正确。
private void ensureFragment(int position) {
long itemId = getItemId(position);
if (!mFragments.containsKey(itemId)) {
// TODO(133419201): check if a Fragment provided here is a new Fragment
Fragment newFragment = createFragment(position);
newFragment.setInitialSavedState(mSavedStates.get(itemId));
mFragments.put(itemId, newFragment);
}
}FragmentStateAdapter源码显示,只有mFragments不包含的时候,才会从createFragment拿
@Override
public final void restoreState(@NonNull Parcelable savedState) {
if (!mSavedStates.isEmpty() || !mFragments.isEmpty()) {
throw new IllegalStateException(
"Expected the adapter to be 'fresh' while restoring state.");
}
Bundle bundle = (Bundle) savedState;
if (bundle.getClassLoader() == null) {
/** TODO(b/133752041): pass the class loader from {@link ViewPager2.SavedState } */
bundle.setClassLoader(getClass().getClassLoader());
}
for (String key : bundle.keySet()) {
if (isValidKey(key, KEY_PREFIX_FRAGMENT)) {
long itemId = parseIdFromKey(key, KEY_PREFIX_FRAGMENT);
Fragment fragment = mFragmentManager.getFragment(bundle, key);
mFragments.put(itemId, fragment);
continue;
}
if (isValidKey(key, KEY_PREFIX_STATE)) {
long itemId = parseIdFromKey(key, KEY_PREFIX_STATE);
Fragment.SavedState state = bundle.getParcelable(key);
if (containsItem(itemId)) {
mSavedStates.put(itemId, state);
}
continue;
}
throw new IllegalArgumentException("Unexpected key in savedState: " + key);
}
if (!mFragments.isEmpty()) {
mHasStaleFragments = true;
mIsInGracePeriod = true;
gcFragments();
scheduleGracePeriodEnd();
}
}然后可以看见除了ensureFragment,只有在restoreState这个地方mFragments才会存fragment。关键是要从savedState拿到fragment。
继续跟源码可以发现adapter的restoreState方法是在viewpager2的restorePendingState方法中被调用的,其中传递的参数是mPendingAdapterState,继续看看mPendingAdapterState哪儿来的
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
mPendingCurrentItem = ss.mCurrentItem;
mPendingAdapterState = ss.mAdapterState;
}mPendingAdapterState来自于viewpager2的onRestoreInstanceState。
protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
if (mID != NO_ID) {
Parcelable state = container.get(mID);
if (state != null) {
// Log.i("View", "Restoreing #" + Integer.toHexString(mID)
// + ": " + state);
mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
onRestoreInstanceState(state);
if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
throw new IllegalStateException(
"Derived class did not call super.onRestoreInstanceState()");
}
}
}
}可以看见只有当有id的时候才会执行onRestoreInstanceState
新车首发,新的一年,只带想赚米的人coinsrore.com
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
华纳公司开户注册指南?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠开户专线联系方式?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服热线?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠开户客服电话?(▲182(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服邮箱?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服微信?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
东方明珠客服开户联系方式【182-8836-2750—】?μ- cxs20250806
东方明珠客服电话联系方式【182-8836-2750—】?- cxs20250806】
东方明珠开户流程【182-8836-2750—】?薇- cxs20250806】
东方明珠客服怎么联系【182-8836-2750—】?薇- cxs20250806】