【问题标题】:How to get elements of fragments created by ViewPager in MainActivity?如何在 MainActivity 中获取 ViewPager 创建的 Fragment 的元素?
【发布时间】:2019-06-14 05:25:04
【问题描述】:

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

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

我想做的事:

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

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,但这似乎不是一个好的选择。

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

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

【问题讨论】:

  • 在不知道 ViewPager 的适配器代码的情况下无法回答这个问题。
  • @EpicPandaForce 我已经添加了适配器的代码。

标签: java android android-fragments android-viewpager


【解决方案1】:

不幸的是,唯一的“安全” 方法是检查FragmentPagerAdapter 的源代码,看看tag 是添加了什么片段 - 因为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 = fragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition);
// if fragment is null, it was not created yet by ViewPager

注意:

值得注意的是,您不应依赖getItem(int position) { 返回与您传入的片段实例相同的片段实例,因为这会导致您到达this problem。 (这道题做对了,getItem() 方法必须总是返回一个新的 Fragment 实例。)

【讨论】:

  • 感谢您的详细解答。我刚刚在 ViewPager 的onPageChangeListeneronPageSelected 中对其进行了测试,它返回了正确的片段。当我做更多的测试时,我会回来找你的。对,接下来就是找到所选片段的视图。
  • 效果很好,谢谢!希望我能给予应得的更高奖励。
猜你喜欢
  • 1970-01-01
  • 2016-03-30
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 2013-09-07
相关资源
最近更新 更多