我使用一个ViewPager和一个FragmentStatePagerAdapter来托管三个不同的片段:

(Fragment1) (Fragment2) (Fragment3)

当我想从FragmentActivity中的ViewPager中获取Fragment1时。

问题是什么,我该如何解决它?


当前回答

我用一种不同的方法简单地实现了这一点。

我的自定义FragmentAdapter。getItem方法返回的不是新的MyFragment(),而是在FragmentAdapter构造函数中创建的MyFragment实例。

在我的活动中,我然后从适配器获得片段,检查它是否是需要的片段的instanceOf,然后强制转换和使用所需的方法。

其他回答

我找不到一个简单干净的方法来做这件事。然而,ViewPager小部件只是另一个ViewGroup,它承载着你的片段。ViewPager将这些片段作为直接子片段。所以你可以遍历它们(使用. getchildcount()和. getchildat()),看看你正在寻找的片段实例当前是否加载到ViewPager中,并获得对它的引用。例如,你可以使用一些静态的唯一ID字段来区分片段。

注意,ViewPager可能没有加载你正在寻找的片段,因为它是一个像ListView一样的虚拟化容器。

主要答案依赖于框架生成的名称。如果这种情况发生变化,那么它将不再起作用。

这个解决方案怎么样,重写你的Fragment(State)PagerAdapter的instantiateItem()和destroyItem():

public class MyPagerAdapter extends FragmentStatePagerAdapter {
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

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

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

    @Override
    public Fragment getItem(int position) {
        return MyFragment.newInstance(...); 
    }

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

在处理可用的Fragments时,这似乎对我有用。尚未实例化的片段在调用getRegisteredFragment时将返回null。但我一直在使用这个主要是为了获得当前片段的ViewPager: adapter . getregisteredfragment (viewpage . getcurrentitem()),这不会返回null。

我不知道这个解决方案还有什么其他缺点。如果有的话,我想知道。

我处理它首先使所有片段的列表(list <Fragment> fragments;),我将使用,然后将它们添加到分页器,使其更容易处理当前查看的片段。

So:

@Override
onCreate(){
    //initialise the list of fragments
    fragments = new Vector<Fragment>();

    //fill up the list with out fragments
    fragments.add(Fragment.instantiate(this, MainFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, MenuFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, StoresFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, AboutFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, ContactFragment.class.getName()));


    //Set up the pager
    pager = (ViewPager)findViewById(R.id.pager);
    pager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments));
    pager.setOffscreenPageLimit(4);
}

那么这个就可以叫做

public Fragment getFragment(ViewPager pager){   
    Fragment theFragment = fragments.get(pager.getCurrentItem());
    return theFragment;
}

然后我可以把它扔进if语句中只有在正确的片段上才会运行

Fragment tempFragment = getFragment();
if(tempFragment == MyFragmentNo2.class){
    MyFragmentNo2 theFrag = (MyFragmentNo2) tempFragment;
    //then you can do whatever with the fragment
    theFrag.costomFunction();
}

但这只是我的hack和slash方法,但它为我工作,我用它做相关的改变,我目前显示的片段,当后退按钮被按下。

我用一种不同的方法简单地实现了这一点。

我的自定义FragmentAdapter。getItem方法返回的不是新的MyFragment(),而是在FragmentAdapter构造函数中创建的MyFragment实例。

在我的活动中,我然后从适配器获得片段,检查它是否是需要的片段的instanceOf,然后强制转换和使用所需的方法。

在片段

public int getArgument(){
   return mPage;
{
public void update(){

}

在FragmentActivity

List<Fragment> fragments = getSupportFragmentManager().getFragments();
for(Fragment f:fragments){
    if((f instanceof PageFragment)&&(!f.isDetached())){
          PageFragment pf = (PageFragment)f;   
          if(pf.getArgument()==pager.getCurrentItem())pf.update();
    }
}