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

(Fragment1) (Fragment2) (Fragment3)

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

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


当前回答

好的适配器FragmentStatePagerAdapter我基金一个解决方案:

在你的FragmentActivity:

ActionBar mActionBar = getSupportActionBar(); 
mActionBar.addTab(mActionBar.newTab().setText("TAB1").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment1.class.getName())));
mActionBar.addTab(mActionBar.newTab().setText("TAB2").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment2.class.getName())));
mActionBar.addTab(mActionBar.newTab().setText("TAB3").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment3.class.getName())));

viewPager = (STViewPager) super.findViewById(R.id.viewpager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), mActionBar);
viewPager.setAdapter(this.mPagerAdapter);

在你的类FragmentActivity中创建一个方法——这样你就可以访问你的Fragment,你只需要给它你想要的Fragment的位置:

public Fragment getActiveFragment(int position) {
String name = MyPagerAdapter.makeFragmentName(position);
return getSupportFragmentManager().findFragmentByTag(name);
}

在适配器中:

public class MyPagerAdapter extends FragmentStatePagerAdapter {

private final ActionBar actionBar;
private final FragmentManager fragmentManager;

public MyPagerAdapter(FragmentManager fragmentManager, com.actionbarsherlock.app.ActionBarActionBar mActionBar) {super(fragmentManager);
this.actionBar = mActionBar;
this.fragmentManager = fragmentManager;
}

@Override
public Fragment getItem(int position) {
getSupportFragmentManager().beginTransaction().add(mTchatDetailsFragment, makeFragmentName(position)).commit();
return (Fragment)this.actionBar.getTabAt(position);
}

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

@Override
public CharSequence getPageTitle(int position) {
return this.actionBar.getTabAt(position).getText();
}

private static String makeFragmentName(int viewId, int index) {
return "android:fragment:" + index;
}

}

其他回答

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

这个解决方案怎么样,重写你的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。

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

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

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

嘿,我已经回答了这个问题。基本上,你需要重写

实例化对象(ViewGroup容器,int位置)

FragmentStatePagerAdapter的方法。

FragmentPagerAdapter是片段的工厂。如果一个片段仍然在内存中,使用下面的方法查找它的位置:

public Fragment findFragmentByPosition(int position) {
    FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
    return getSupportFragmentManager().findFragmentByTag(
            "android:switcher:" + getViewPager().getId() + ":"
                    + fragmentPagerAdapter.getItemId(position));
}

v4支持api的示例代码。

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

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

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