I\'m using a ViewPager
together with a FragmentStatePagerAdapter
to host three different fragments:
Another simple solution:
public class MyPagerAdapter extends FragmentPagerAdapter {
private Fragment mCurrentFragment;
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
//...
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentFragment() != object) {
mCurrentFragment = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
}
Create integer resource id in /values/integers.xml
<integer name="page1">1</integer>
<integer name="page2">2</integer>
<integer name="page3">3</integer>
Then in PagerAdapter getItem function:
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = FragmentOne.newInstance();
mViewPager.setTag(R.integer.page1,fragment);
}
else if (position == 1) {
fragment = FragmentTwo.newInstance();
mViewPager.setTag(R.integer.page2,fragment);
} else if (position == 2) {
fragment = FragmentThree.newInstance();
mViewPager.setTag(R.integer.page3,fragment);
}
return fragment;
}
Then in activity write this function to get fragment reference:
private Fragment getFragmentByPosition(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = (Fragment) mViewPager.getTag(R.integer.page1);
break;
case 1:
fragment = (Fragment) mViewPager.getTag(R.integer.page2);
break;
case 2:
fragment = (Fragment) mViewPager.getTag(R.integer.page3);
break;
}
return fragment;
}
Get the fragment reference by calling the above function and then cast it to your custom fragment:
Fragment fragment = getFragmentByPosition(position);
if (fragment != null) {
FragmentOne fragmentOne = (FragmentOne) fragment;
}
I know this has a few answers, but maybe this will help someone. I have used a relatively simple solution when I needed to get a Fragment
from my ViewPager
. In your Activity
or Fragment
holding the ViewPager
, you can use this code to cycle through every Fragment
it holds.
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
Fragment viewPagerFragment = fragmentPagerAdapter.getItem(i);
if(viewPagerFragment != null) {
// Do something with your Fragment
// Check viewPagerFragment.isResumed() if you intend on interacting with any views.
}
}
If you know the position of your Fragment
in the ViewPager
, you can just call getItem(knownPosition)
.
If you don't know the position of your Fragment
in the ViewPager
, you can have your children Fragments
implement an interface with a method like getUniqueId()
, and use that to differentiate them. Or you can cycle through all Fragments
and check the class type, such as if(viewPagerFragment instanceof FragmentClassYouWant)
!!! EDIT !!!
I have discovered that getItem
only gets called by a FragmentPagerAdapter
when each Fragment
needs to be created the first time, after that, it appears the the Fragments
are recycled using the FragmentManager
. This way, many implementations of FragmentPagerAdapter
create new Fragment
s in getItem
. Using my above method, this means we will create new Fragment
s each time getItem
is called as we go through all the items in the FragmentPagerAdapter
. Due to this, I have found a better approach, using the FragmentManager
to get each Fragment
instead (using the accepted answer). This is a more complete solution, and has been working well for me.
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
String name = makeFragmentName(mViewPager.getId(), i);
Fragment viewPagerFragment = getChildFragmentManager().findFragmentByTag(name);
// OR Fragment viewPagerFragment = getFragmentManager().findFragmentByTag(name);
if(viewPagerFragment != null) {
// Do something with your Fragment
if (viewPagerFragment.isResumed()) {
// Interact with any views/data that must be alive
}
else {
// Flag something for update later, when this viewPagerFragment
// returns to onResume
}
}
}
And you will need this method.
private static String makeFragmentName(int viewId, int position) {
return "android:switcher:" + viewId + ":" + position;
}
in TabLayout there are multiple tab for Fragment. you can find the fragment by Tag using the index of the fragment.
For ex. the index for Fragment1 is 0, so in findFragmentByTag()
method, pass the tag for the Viewpager.after using fragmentTransaction you can add,replace the fragment.
String tag = "android:switcher:" + R.id.viewPager + ":" + 0;
Fragment1 f = (Fragment1) getSupportFragmentManager().findFragmentByTag(tag);
You don't need to call getItem()
or some other method at later stage to get the reference of a Fragment
hosted inside ViewPager
. If you want to update some data inside Fragment
then use this approach: Update ViewPager dynamically?
Key is to set new data inside Adaper
and call notifyDataSetChanged()
which in turn will call getItemPosition()
, passing you a reference of your Fragment
and giving you a chance to update it. All other ways require you to keep reference to yourself or some other hack which is not a good solution.
@Override
public int getItemPosition(Object object) {
if (object instanceof UpdateableFragment) {
((UpdateableFragment) object).update(xyzData);
}
//don't return POSITION_NONE, avoid fragment recreation.
return super.getItemPosition(object);
}
Fragment yourFragment = yourviewpageradapter.getItem(int index);
index
is the place of fragment in adapter like you added fragment1
first so retreive fragment1
pass index
as 0 and so on for rest