I'm using a ViewPager
together with a FragmentStatePagerAdapter
to host three different fragments:
- [Fragment1]
- [Fragment2]
- [Fragment3]
When I want to get Fragment1
from the ViewPager
in the FragmentActivity
.
What is the problem, and how do I fix it?
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 myViewPager
. In yourActivity
orFragment
holding theViewPager
, you can use this code to cycle through everyFragment
it holds.If you know the position of your
Fragment
in theViewPager
, you can just callgetItem(knownPosition)
.If you don't know the position of your
Fragment
in theViewPager
, you can have your childrenFragments
implement an interface with a method likegetUniqueId()
, and use that to differentiate them. Or you can cycle through allFragments
and check the class type, such asif(viewPagerFragment instanceof FragmentClassYouWant)
!!! EDIT !!!
I have discovered that
getItem
only gets called by aFragmentPagerAdapter
when eachFragment
needs to be created the first time, after that, it appears the theFragments
are recycled using theFragmentManager
. This way, many implementations ofFragmentPagerAdapter
create newFragment
s ingetItem
. Using my above method, this means we will create newFragment
s each timegetItem
is called as we go through all the items in theFragmentPagerAdapter
. Due to this, I have found a better approach, using theFragmentManager
to get eachFragment
instead (using the accepted answer). This is a more complete solution, and has been working well for me.And you will need this method.
I couldn't find a simple, clean way to do this. However, the ViewPager widget is just another ViewGroup , which hosts your fragments. The ViewPager has these fragments as immediate children. So you could just iterate over them (using .getChildCount() and .getChildAt() ), and see if the fragment instance that you're looking for is currently loaded into the ViewPager and get a reference to it. E.g. you could use some static unique ID field to tell the fragments apart.
Note that the ViewPager may not have loaded the fragment you're looking for since it's a virtualizing container like ListView.
FragmentPagerAdapter is the factory of the fragments. To find a fragment based on its position if still in memory use this:
Sample code for v4 support api.
In Fragment
In FragmentActivity
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);
The main answer relies on a name being generated by the framework. If that ever changes, then it will no longer work.
What about this solution, overriding
instantiateItem()
anddestroyItem()
of yourFragment(State)PagerAdapter
:This seems to work for me when dealing with Fragments that are available. Fragments that have not yet been instantiated, will return null when calling
getRegisteredFragment
. But I've been using this mostly to get the currentFragment
out of theViewPager
:adapater.getRegisteredFragment(viewPager.getCurrentItem())
and this won't returnnull
.I'm not aware of any other drawbacks of this solution. If there are any, I'd like to know.