如何在MainActivity中获取ViewPager创建的fragments的元素?

How to get elements of fragments created by ViewPager in MainActivity?

我有几个片段是用 ViewPager 组织的。我在 MainActivity 的 onCreate 方法中向 ViewPager 添加了一个 addOnPageChangeListener,它给出了所选片段的位置。

尽管我通过声明 setOffscreenPageLimit 来防止片段自我破坏,但我仍然没有想出如何从 MainActivity 访问片段,只需使用 findViewById returns空对象异常。

我想做的事情:

我想访问片段的元素,例如布局和滚动视图,在 ViewPager:

OnPageListener
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override
    public void onPageSelected(int i) {

        if(i == 0) {
            // Do something with the first fragment.
        } else if(i == 1) {
            // Do something with the second fragment.
        }

    }

}

ViewPager使用FragmentPagerAdapter:

public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                return Fragment1.newInstance(position);
            case 1:
                return Fragment2.newInstance(position);
            case 2:
                return Fragment3.newInstance(position);
            case 3:
                return Fragment4.newInstance(position);
            default:
                throw new IllegalArgumentException();
        }
    }

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

这是这样添加的:

mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);

~

或者我应该改变我的方法吗?

如果使用此设计无法实现访问片段,那么有效的替代路由是什么?

我试过在自定义 ViewPager 中实现 ViewPager.onPageChangeListener,但这似乎不是一个好的选择。

我可以处理它们各自片段中的元素,但这是一个乏味的过程并且难以维护,这是我寻找一种同时处理它们的方法的原因。

我知道以前有人问过类似的问题,但我没有找到解决方案。

不幸的是,唯一的 "safe" 方法是检查 FragmentPagerAdapter 的源代码,看看 tag 是什么fragment 添加 - 因为 findFragmentByTag 是从 FragmentManager 获取 Fragment 的唯一安全方法。

当然,我们需要希望这个实现细节不会在支持库版本之间改变,但实际上它多年来没有改变:)


无论如何,FragmentPagerAdapter 说:

    // Do we already have this fragment?
    String name = makeFragmentName(container.getId(), itemId);
    Fragment fragment = mFragmentManager.findFragmentByTag(name);

那什么是name

private static String makeFragmentName(int viewId, long id) {
    return "android:switcher:" + viewId + ":" + id;
}

什么是viewId,什么是id

ViewId 是 container.getId(),其中 containerViewPager 本身。

id 是:final long itemId = getItemId(position); 默认情况下是 return position;.


所以可以找到Fragment如下:

Fragment fragment = fragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);
// if fragment is null, it was not created yet by ViewPager

注意:

值得注意的是,你不应该依赖 getItem(int position) { 到 return 与你传入的相同片段实例 ,因为那会引导你至 。 (这个问题做对了,getItem() 方法必须总是 return 一个新的 Fragment 实例。)