从Activity调用选项卡片段方法

9

我有一个包含三个片段的活动。这些片段使用PagerAdapter使用操作栏选项卡进行操作。我想要做的是从主活动中访问当前选项卡片段中的方法。我尝试了下面的代码,但它只返回null片段,所以我猜它无法在选项卡中找到它!

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

有人能给些建议吗?我已经花了大约6个小时,但是我还没有解决这个问题。


你能展示一下你的 PagerAdapter 吗? - Stephane Mathis
添加了分页适配器 - 谢谢 - user2029541
4个回答

23

你应该这样做:只创建一次每个片段,然后将其提供给所有调用getItem方法的对象。

例如:

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

} 

现在,即使你在你的活动中,你也可以调用getItem

如果你想调用特定的方法,你只需要将它转换为真实的片段类。

int pos = viewpager.getCurrentItem();    
Fragment activeFragment = adapter.getItem(pos);
if(pos == 0)
    ((NPListFragment)activeFragment).refreshT();
...

1
不错的解决方案,但是在fragment中尝试访问视图时出现了空指针异常。这只发生在我重置适配器后访问视图。有什么想法吗? - VinKrish
3
这将创建另一个空的片段,它们的视图将为空。您需要注册先前创建的片段,并通过getter方法访问它们。 - Egemen Hamutçu

7

在填充过程中,您需要注册您的碎片并从外部访问它们。

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

现在你可以从外部获取已注册的片段。
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;
    }
}

1
我使用片段管理器来获取片段。我的片段在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;
    }

然后在MainActivity中 -

List<Fragment> fragments = getSupportFragmentManager().getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                if (fragment instanceof Fragment1) {
                    ((Fragment1) fragment).fragmentOne();
                    break;
                }
            }
        }

1
我解决了这个问题。
这是因为当调用getItem时,Adapter每次都会初始化一个新的Fragment。
要解决这个问题,你需要在onCreate方法中创建一个所需Fragment的数组。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接