我在Android应用中遇到了一个非常难以诊断的问题。 getUserVisibleHint()
在false
中当前选定的片段返回ViewPager
时应返回true(因为它是可见的并且已选中)。
我已经将我看到这种行为的实例描述如下:
ViewPager
FragmentStatePagerAdapter
PagerAdapter
恢复
答案 0 :(得分:7)
调试显示FragmentStatePagerAdapter
实际上正在setPrimaryItem(ViewGroup container, int position, Object object)
中正确设置所选标签的状态,但后来在FragmentManager#moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)
//from FragmentManager#moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive)
f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
上面的 f.mSavedFragmentState
已将可见状态保存为false
,因为当片段不再显示在屏幕上时已保存。
所以这里的问题是国家损失;可见状态在FragmentStatePagerAdapter#setPrimaryItem
中设置,但在调用片段的onResume
方法之前丢失了一段时间。
在库中修复此错误之前,覆盖setPrimaryItem
中的PagerAdapter
并强制首先提交任何待处理的事务。
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
//Force any pending transactions to save before we set an item as primary
finishUpdate(null);
super.setPrimaryItem(container, position, object);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return 4;
}
@Override
public CharSequence getPageTitle(int position) {
return "Page " + (position + 1);
}
}
要解决此问题,FragmentStatePagerAdapter
必须在设置用户可见提示之前提交任何片段事务。
FragmentStatePagerAdapter
只是为了展示FragmentStatePagerAdapter
@Override
public Object instantiateItem(ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);
if (f != null) {
return f;
}
}
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
Fragment fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
if (mSavedState.size() > position) {
Fragment.SavedState fss = mSavedState.get(position);
if (fss != null) {
fragment.setInitialSavedState(fss);
}
}
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
mCurTransaction.add(container.getId(), fragment);
return fragment;
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
@Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitNowAllowingStateLoss();
mCurTransaction = null;
}
}
答案 1 :(得分:1)
如果它与您的项目兼容,请尝试支持库的27.1.1
(或更新版本)版本。 related bug report在2018年2月下旬标记为固定,版本27.1.1
于2018年4月发布。