我有ViewPager
(扩展FragmentPagerAdapter
),其中包含两个Fragments
。我需要的是,当我在其中滑动时,为每个ListView
刷新Fragment
。为此,我实现了ViewPager.OnPageChangeListener
接口(即onPageScrollStateChanged
)。为了保留对Fragment
的引用,我使用HashTable
。我在Fragments
方法中将HashTable
的引用存储在getItem()
中:
@Override
public Fragment getItem(int num) {
if (num == 0) {
Fragment itemsListFragment = new ItemsListFragment();
mPageReferenceMap.put(num, itemsListFragment);
return itemsListFragment;
} else {
Fragment favsListFragment = new ItemsFavsListFragment();
mPageReferenceMap.put(num, favsListFragment);
return favsListFragment;
}
}
因此,当我从一个Fragment
切换到另一个onPageScrollStateChanged
触发器时,我使用HashTable
在Fragments
(刷新)中调用所需的方法:
public void refreshList() {
((ItemsListFragment) mPageReferenceMap.get(0)).refresh();
((ItemsFavsListFragment) mPageReferenceMap.get(1)).refresh();
}
在orientation change
事件发生之前一切正常。之后是refresh()
方法中的代码,即:
public void refresh() {
mAdapter.changeCursor(mDbHelper.getAll());
getListView().setItemChecked(-1, true); // The last row from a exception trace finishes here (my class).
}
结果为IllegalStateException
:
java.lang.IllegalStateException: Content view not yet created
at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
at ebeletskiy.gmail.com.passwords.ui.ItemsFavsListFragment.refresh(ItemsFavsListFragment.java:17)
假设确实未创建Content
视图,我将boolean
方法中的onActivityCreated()
变量设置为true
并使用if/else
条件调用{{1}或者不显示成功创建的活动和内容视图。
然后我正在调试以查看getListView()
何时调用FragmentPagerAdapter
,并且在getItem()
事件之后不会调用该方法。所以看起来它orientation change
包含对旧ViewPager
的引用。这只是我的假设。
那么,有没有办法强制Fragments
再次调用ViewPager
,所以我可以使用对当前getItem()
的正确引用?可能是其他一些解决方案?非常感谢你。
答案 0 :(得分:4)
然后我正在调试以查看FragmentPagerAdapter何时调用getItem(),并且在方向更改事件之后不会调用该方法。看起来它看起来像ViewPager持有对旧碎片的引用。
应该自动重新创建片段,就像配置更改中的任何片段一样。例外情况是你使用setRetainInstance(true)
,在这种情况下它们应该是和以前一样的片段对象。
那么,有没有办法强制ViewPager再次调用getItem(),所以我可以使用对当前片段的正确引用?
那里的碎片有什么问题?
答案 1 :(得分:0)
我花了几天时间寻找这个问题的解决方案,并找出了很多要点:
使用FragmentPagerAdapter
代替FragmentStatePagerAdapter
使用FragmentStatePagerAdapter
代替FragmentPagerAdapter
在[{1}}覆盖FragmentPagerAdapter
POSITION_NONE
如果您需要对片段进行动态更改,请不要使用FragmentPagerAdapter
以及许多其他人......
在我的应用中,例如Eugene,我自己管理了已创建片段的实例。我将它保存在一个专门的类中的getItemPosition
内,因此片段永远不会被释放,从而加速我的应用程序(但消耗更多资源)。
问题出在我旋转平板电脑(和手机)时。该片段不再调用HashMap<String,Fragment>
,我无法对其进行更改。
我真的花了很多时间才真正找到了解决方案,所以我需要与StackOverflow社区分享,他们帮助了我很多次......
解决这个问题的方法虽然很难找到,但很简单:
只需在FragmentPagerAdapter的构造函数中保留对FragmentManager的引用:
getItem(int)
多数民众赞成。它会像魅力一样......
答案 2 :(得分:0)
您可以清除保存的实例状态
protected void onCreate(Bundle savedInstanceState) {
clearBundle(savedInstanceState);
super.onCreate(savedInstanceState, R.layout.activity_car);
}
private void clearBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
savedInstanceState.remove("android:fragments");
savedInstanceState.remove("android:support:fragments");
savedInstanceState.remove("androidx.lifecycle.BundlableSavedStateRegistry.key");
savedInstanceState.remove("android:lastAutofillId");
}
}