如何在 MainActivity 中获取 ViewPager 创建的片段元素? [英] How to get elements of fragments created by ViewPager in MainActivity?

查看:18
本文介绍了如何在 MainActivity 中获取 ViewPager 创建的片段元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我想做什么:

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

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@覆盖公共无效 onPageSelected(int i) {如果(我== 0){//对第一个片段做一些事情.} else if(i == 1) {//对第二个片段做一些事情.}}}

ViewPager 使用一个 FragmentPagerAdapter:

public class SectionsPagerAdapter extends FragmentPagerAdapter {公共 SectionsPagerAdapter(FragmentManager fm) {超级(调频);}@覆盖公共片段 getItem(int position) {开关(位置){案例0:返回 Fragment1.newInstance(position);情况1:返回 Fragment2.newInstance(position);案例2:返回 Fragment3.newInstance(position);案例3:返回 Fragment4.newInstance(position);默认:抛出新的 IllegalArgumentException();}}@覆盖公共 int getCount() {返回 4;}}

是这样添加的:

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

~

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

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

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

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

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

解决方案

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

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

<小时>

无论如何,所以 FragmentPagerAdapter 说:

<块引用>

//我们已经有这个片段了吗?String name = makeFragmentName(container.getId(), itemId);片段片段 = mFragmentManager.findFragmentByTag(name);

那么什么是name?

<块引用>

private static String makeFragmentName(int viewId, long id) {返回 "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);//如果片段为空,则它尚未被 ViewPager 创建

<小时>

注意:

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

I have several fragments which are organized with a ViewPager. I add an addOnPageChangeListener to the ViewPager in MainActivity's onCreate method which gives the position of the selected fragment.

Even though I prevent the fragments from destroying themselves with stating a setOffscreenPageLimit, I still haven't figured out how to access fragments from MainActivity, as simply using findViewById returns null object exceptions.

What I want to do:

I would like to access elements of fragments, e.g. layouts and scrollviews, in the OnPageListener of the ViewPager:

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

    }

}

The ViewPager uses a 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;
    }
}

Which is added like this:

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

~

Or should I change my approach?

If accessing fragments cannot be achieved with this design, what could be an effective alternative route?

I've tried to implement ViewPager.onPageChangeListener in the custom ViewPager, but it didn't seem to be a good option.

I could deal with the elements in their respective fragments, but this is a tedious process and hard to maintain, which I the reason I look for a way to handle them simultaneously.

I know similar questions have been asked before, but I didn't find a solution in them.

解决方案

Unfortunately the only "safe" way to do it is to check the source code of FragmentPagerAdapter, and see what tag is the fragment is added with - because findFragmentByTag is the only safe way to get a Fragment from a FragmentManager.

Of course, we need to hope that this implementation detail doesn't change between support library versions, but it actually hasn't changed in years :)


Anyways, so FragmentPagerAdapter says:

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

So what is name?

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

What is viewId and what is id?

ViewId is container.getId(), where container is the ViewPager itself.

id is: final long itemId = getItemId(position); which by default is return position;.


So you can find the Fragment as follows:

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


NOTE:

It is worth noting that you should NOT rely on getItem(int position) { to return the same fragment instance as you passed in, because that will lead you to this problem. (This question does it correctly, the getItem() method must always return a new Fragment instance.)

这篇关于如何在 MainActivity 中获取 ViewPager 创建的片段元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆