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

Erl*_*.H. 1 java android android-fragments android-viewpager

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

尽管我通过声明 a 来防止片段自行销毁setOffscreenPageLimit,但我仍然没有弄清楚如何从 MainActivity 访问片段,因为简单地使用findViewById会返回空对象异常。

我想做的事:

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

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

    }

}
Run Code Online (Sandbox Code Playgroud)

使用ViewPagerFragmentPagerAdapter

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

添加如下:

mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
Run Code Online (Sandbox Code Playgroud)

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

如果这种设计无法实现访问片段,那么有效的替代路线是什么?

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

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

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

Epi*_*rce 6

不幸的是,唯一“安全”的方法是检查 的源代码FragmentPagerAdapter,并查看tag片段添加了什么 - 因为findFragmentByTag这是从 FragmentManager 获取片段的唯一安全方法。

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


无论如何,FragmentPagerAdapter 说:

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

那么什么是name

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

什么是viewId又是什么id

ViewId 是container.getId(),哪里container是它ViewPager本身。

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
Run Code Online (Sandbox Code Playgroud)

笔记:

值得注意的是,您不应该依赖getItem(int position) {返回与传入的相同的片段实例,因为这会导致您遇到此问题。(这个问题做得正确,该getItem()方法必须始终返回一个新的 Fragment 实例。)