I,m using slidingTabLayout with 4 tabs and a viewpager and 4 fragment class for every tab.
i need to reload one of my fragments (first tab) in my project when user
There are couple of solution for this.
1). When the FragmentPagerAdapter
adds a Fragment
to the FragmentManager
, it uses a special tag based on the particular position that the Fragment
will be placed. So you can simply get the current visible Fragment
in your ViewPager
using these lines of code
Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
// based on the current position you can then cast the page to the correct Fragment class and call some method inside that fragment to reload the data:
if (0 == ViewPager.getCurrentItem() && null != fragment) {
((TabFragment1)fragment).reloadFragmentData();
}
2). You should keep track of all the active fragments in the FragmentStatePagerAdapter
. For demo sample you can refer to second approach here
3). You can make use of EventBus
to post events to your Fragment
from anywhere. All you have to do is to register your Fragment
for that specific event. For official documentation refer this
Here is the method which is used by FragmentPagerAdapter
to create the Fragment
's tag name:
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
viewId
is the id of the ViewPager
.
id
is the position of the fragment inside the ViewPager
.
Example:
String fragmentTag = makeFragmentName(myViewPager.getId(), 2);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
Though this question has already been answered. I have another approach for achiving this and this might be better one as the way fragments are tagged in the code are subjected to change. Also to point out using adapter.getItem(position) does not return the instance of fragment being displayed, it will depend on our own implementation of getItem method.
So Basically the problem is that we do not have the instance of Fragments that are present in the viewPager. The idea is to override method
public Object instantiateItem(ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);
if (f != null) {
return f;
}
}
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
Fragment fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
if (mSavedState.size() > position) {
Fragment.SavedState fss = mSavedState.get(position);
if (fss != null) {
fragment.setInitialSavedState(fss);
}
}
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
mCurTransaction.add(container.getId(), fragment);
return fragment;
}
of FragmentStatePagerAdapter. If we look at the default implementation of this method, it basically does the job of instantiating new Fragments if they do not exists and returning them. Also it stores them in a list of fragments which is private. So what we can do is Override this method and store the instances on fragments in our own list. This can be implemented in the following way
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
private ArrayList<Fragment> fragmentList;
private final int NUM_PAGES;
public ScreenSlidePagerAdapter(FragmentManager fm, int numPages) {
super(fm);
NUM_PAGES = numPages;
fragmentList = new ArrayList<>(NUM_PAGES);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new CustomFragment();
//this method can be modified according to the requirement
return fragment;
}
@Override
public int getCount() {
return NUM_PAGES;
}
public Fragment getFragment(int position){
return fragmentList.get(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position){
Fragment fragment = (Fragment) super.instantiateItem(container,position);
if(fragmentList.size()<NUM_PAGES&&!fragmentList.contains(fragment)){
fragmentList.add(fragment);
}
return fragment;
}
}
Therefore we will have the instances of all the fragments available with us we would no longer need any tags to find the fragment instances being displayed to the user.