I\'m using the v4 compatibility ViewPager in Android. My FragmentActivity has a bunch of data which is to be displayed in different ways on different pages in my ViewPager.
Also works without problems:
somewhere in page fragment's layout:
<FrameLayout android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone" android:id="@+id/fragment_reference">
<View android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
</FrameLayout>
in fragment's onCreateView():
...
View root = inflater.inflate(R.layout.fragment_page, container, false);
ViewGroup ref = (ViewGroup)root.findViewById(R.id.fragment_reference);
ref.setTag(this);
ref.getChildAt(0).setTag("fragment:" + pageIndex);
return root;
and method to return Fragment from ViewPager, if exists:
public Fragment getFragment(int pageIndex) {
View w = mViewPager.findViewWithTag("fragment:" + pageIndex);
if (w == null) return null;
View r = (View) w.getParent();
return (Fragment) r.getTag();
}
I want to give my approach in case it can help anyone else:
This is my pager adapter:
public class CustomPagerAdapter extends FragmentStatePagerAdapter{
private Fragment[] fragments;
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
fragments = new Fragment[]{
new FragmentA(),
new FragmentB()
};
}
@Override
public Fragment getItem(int arg0) {
return fragments[arg0];
}
@Override
public int getCount() {
return fragments.length;
}
}
In my activity I have:
public class MainActivity {
private ViewPager view_pager;
private CustomPagerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new CustomPagerAdapter(getSupportFragmentManager());
view_pager = (ViewPager) findViewById(R.id.pager);
view_pager.setAdapter(adapter);
view_pager.setOnPageChangeListener(this);
...
}
}
Then to get the current fragment what I do is:
int index = view_pager.getCurrentItem();
Fragment currentFragment = adapter.getItem(index);
If you ask me, the second solution on the below page, keeping track of all the "active" fragment pages, is better: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html
The answer from barkside is too hacky for me.
you keep track of all the "active" fragment pages. In this case, you keep track of the fragment pages in the FragmentStatePagerAdapter, which is used by the ViewPager.
private final SparseArray<Fragment> mPageReferences = new SparseArray<Fragment>();
public Fragment getItem(int index) {
Fragment myFragment = MyFragment.newInstance();
mPageReferences.put(index, myFragment);
return myFragment;
}
To avoid keeping a reference to "inactive" fragment pages, we need to implement the FragmentStatePagerAdapter's destroyItem(...) method:
public void destroyItem(View container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferences.remove(position);
}
... and when you need to access the currently visible page, you then call:
int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);
... where the MyAdapter's getFragment(int) method looks like this:
public MyFragment getFragment(int key) {
return mPageReferences.get(key);
}
"
Barkside's answer works with FragmentPagerAdapter
but doesn't work with FragmentStatePagerAdapter
, because it doesn't set tags on fragments it passes to FragmentManager
.
With FragmentStatePagerAdapter
it seems we can get by, using its instantiateItem(ViewGroup container, int position)
call. It returns reference to fragment at position position
. If FragmentStatePagerAdapter
already holds reference to fragment in question, instantiateItem
just returns reference to that fragment, and doesn't call getItem()
to instantiate it again.
So, suppose, I'm currently looking at fragment #50, and want to access fragment #49. Since they are close, there's a good chance the #49 will be already instantiated. So,
ViewPager pager = findViewById(R.id.viewpager);
FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) pager.getAdapter();
MyFragment f49 = (MyFragment) a.instantiateItem(pager, 49)