我从前一刻看着this SO post的解决方案。这个解决方案对我有意义。但是,我在时遇到问题我应该尝试访问当前正在显示的片段。我使用了与关联问题相同的设置:ViewPager
和FragmentStatePagerAdapter
。我已根据解决方案建议对FragmentStatePagerAdapter
实施了调整:
private class MyPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
@Override
public Fragment getItem(int position) {
mCursor.moveToPosition(position);
return ArticleDetailFragment.newInstance(mCursor.getLong(ArticleLoader.Query._ID));
}
@Override
public int getCount() {
return (mCursor != null) ? mCursor.getCount() : 0;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
尝试访问当前片段时出现问题。我尝试在onResume()
内访问它:
@Override
protected void onResume() {
super.onResume();
ArticleDetailFragment fragment = (ArticleDetailFragment)
mPagerAdapter.getRegisteredFragment(mPager.getCurrentItem());
mCallback = (FragmentCallback) fragment;
}
...但我的片段总是空的。这是因为在我的适配器中调用onResume()
之前调用了instantiateItem()
。该片段为null,因为尚未向适配器中的registeredFragments
添加任何片段。
我希望得到一些关于我应该使用哪个活动生命周期方法的指导,其中instantiateItems()
已经被调用,并且我有实际的片段可以使用。与往常一样,任何有关这方面的帮助都将受到赞赏。
我真正想要实现的目的是获取对我的片段的引用,以便我可以实例化我在我的活动中定义的回调接口。我希望使用此界面与ViewPager
中当前显示的片段进行通信。但是,为了能够做到这一点,我首先需要引用当前片段。
答案 0 :(得分:2)
它们的一般规则应该是
不要打电话给我。我打电话给你。
这意味着您应该让Fragment
在可用时通知其他人以及愿意分享哪些数据。您可以使用某种接口和/或回调方法来执行此操作。来自Android文档的Communicating with Other Fragments显示了如何在两个片段之间进行通信。由于此通信通过父活动,因此适用相同的概念。如果要与活动进行通信,则跳过有关将消息发送到其他片段的步骤。
基本思想是你应该给Fragment一个回调而不是使用Fragment作为回调。
答案 1 :(得分:0)
InstantiateItems()
通常会getItem()
调用View
来获取新的Fragment
,理想情况下getItem()
会在put()
方法中创建,因此您需要使用{{ 1}} getItem()
中的方法,如
@Override
public Fragment getItem(int position) {
mCursor.moveToPosition(position);
Fragment createdFragment = ArticleDetailFragment.newInstance(mCursor.getLong(ArticleLoader.Query._ID));
registeredFragments.put(position, createdFragment );
return createdFragment;
} // also remove InstantiateItems() method