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

(Fragment1) (Fragment2) (Fragment3)

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

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


当前回答

Must将FragmentPagerAdapter扩展到你的ViewPager适配器类。 如果你使用FragmentStatePagerAdapter,那么你将无法通过它的ID找到你的Fragment

public static String makeFragmentName(int viewPagerId, int index) {
  return "android:switcher:" + viewPagerId + ":" + index;
}

如何使用这种方法:-

Fragment mFragment = ((FragmentActivity) getContext()).getSupportFragmentManager().findFragmentByTag(
       AppMethodUtils.makeFragmentName(mViewPager.getId(), i)
);
InterestViewFragment newFragment = (InterestViewFragment) mFragment;

其他回答

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

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

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

最好的解决方案是使用我们在CodePath中创建的名为SmartFragmentStatePagerAdapter的扩展。按照这个指南,这使得从ViewPager中检索片段和当前选择的片段变得非常容易。它还可以更好地管理嵌入到适配器中的片段的内存。

最简单、最简洁的方法。如果你在ViewPager中所有的片段都属于不同的类,你可以像下面这样检索并区分它们:

public class MyActivity extends Activity
{

    @Override
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        if (fragment.getClass() == MyFragment.class) {
            mMyFragment = (MyFragment) fragment;
        }
    }

}

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

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

另一个简单的解决方案:

    public class MyPagerAdapter extends FragmentPagerAdapter {
        private Fragment mCurrentFragment;

        public Fragment getCurrentFragment() {
            return mCurrentFragment;
        }
//...    
        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if (getCurrentFragment() != object) {
                mCurrentFragment = ((Fragment) object);
            }
            super.setPrimaryItem(container, position, object);
        }
    }