Call Tabbed Fragment method from Activity
Asked Answered
S

4

9

I have one activity that comprises of three fragments. The fragments use the actionbar tabs using a PagerAdapter. What I want to do is access a method in the active tabbed fragment from the main activity. I have tried the below code but this just returns the fragment as null, so I guess it cant find it within the tabs!

 NPListFragment articleFrag = (NPListFragment) getSupportFragmentManager().findFragmentByTag("NP");
    articleFrag.refreshT();

PagerAdapter:

public class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int i) {
    switch (i) {
        case 0:
            return new NPListFragment();
        case 1:
            return new PListFragment();
        case 2:
            return new FavouritesFragment();
    }
    return null;
}

@Override
public int getCount() {
    return 3;
}

} Can anyone advise? I have spent about 6 hours on this, i'm just not making any progress resolving this.

Schwarzwald answered 12/4, 2015 at 8:44 Comment(2)
Can you show your PagerAdapter ?Upon
added pager adapter - thanksSchwarzwald
U
23

What you should do is : create only once each fragment and then give it for all calls to the getItem method.

For instance :

public class AppSectionsPagerAdapter extends FragmentPagerAdapter {

Fragment one, two, three;

public AppSectionsPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int i) {
    switch (i) {
        case 0:
            if(one == null)
                one = new NPListFragment();
            return one;
        case 1:
            if(two == null)
                two= new PListFragment();
            return two;
        case 2:
            if(three == null)
                three= new FavouritesFragment();
            return three;
    }
    return null;
}

@Override
public int getCount() {
    return 3;
}

} 

Now, even you in your activity you can call getItem

You'll just need to cast it to the real fragment class if you want to call a specific method.

int pos = viewpager.getCurrentItem();    
Fragment activeFragment = adapter.getItem(pos);
if(pos == 0)
    ((NPListFragment)activeFragment).refreshT();
...
Upon answered 12/4, 2015 at 18:16 Comment(2)
nice solution, but i'm getting null pointer exception of views when i tried to access them in fragment. This is happening only after i reset adapter in between accessing views. Any idea?Saltant
This will create another empty fragment and their views will be null. You need to register your previously created fragments and access them by a getter method.Armenia
C
7

You need to register your fragments while populating, then access them from outside.

public class AppSectionsPagerAdapter extends FragmentPagerAdapter {
private SparseArray<Fragment> registeredFragments = new SparseArray<>();
public AppSectionsPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int i) {
    switch (i) {
        case 0:
            return new NPListFragment();
        case 1:
            return new PListFragment();
        case 2:
            return new FavouritesFragment();
    }
    return null;
}

@Override
public int getCount() {
    return 3;
}

@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);
}

Now you can get registeredFragments from outside

int pos = viewpager.getCurrentItem();
Fragment fragment = adapter.getRegisteredFragment(pos);
switch (pos) {
    case 0: {
        ((NPListFragment) fragment).refreshT();
        break;
    }
    case 1: {
        ((PListFragment) fragment).refreshK();
        break;
    }
    case 2: {
        ((FavouritesFragment) fragment).refreshL();
        break;
    }
}
Cordell answered 13/2, 2017 at 12:48 Comment(0)
U
1

I solved this problem.

It is happening because Adapter is initializing every time a new Fragment when get item is called.

To solve this you need to make a array of Required Fragment in onCreate method

Fragment[] FragmentArray;
FragmentArray = new Fragment[] {new Fragment 1,new Fragment 2...};   // all fragment goes in array
...

get item(int position)
...
return FragmentArray[position]
...
Fragment1 f= (Fragment1) FragmentArray[0];
f.refresh()  // call required function
Ushaushant answered 25/4, 2017 at 11:6 Comment(0)
V
1

I use the fragment manager to get the fragment. My fragments are initialised in view pager like below in ViewPagerAdapter.class -

@Override
    public Fragment getItem(int i) {
        Fragment fragment = null;
        switch (i) {
            case 0:
                fragment = Fragment.instantiate(mContext, Fragment1.class.getName());
                break;
            case 1:
                fragment = Fragment.instantiate(mContext, Fragment2.class.getName());
                break;
            case 2:
                fragment = Fragment.instantiate(mContext, Fragment3.class.getName());
                break;
        }
        return fragment;
    }

Then in MainActivity -

List<Fragment> fragments = getSupportFragmentManager().getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                if (fragment instanceof Fragment1) {
                    ((Fragment1) fragment).fragmentOne();
                    break;
                }
            }
        }
Volitant answered 12/6, 2018 at 22:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.