安卓:两个Fragment共用同一个ViewPager XML布局

3
我有一个包含两个并排Fragment的布局的Activity。在每个Fragment中,我都有一个ViewPager。由于我需要两个Fragment看起来相同,所以我使用相同的布局XML文件,其中包含一个ViewPager。
现在当我测试应用程序时,只有第一个Fragment的ViewPager似乎有效。第二个Fragment显示PagerTitleStrip,我可以翻页,但它没有显示ViewPager中的Fragments。
为什么第二个ViewPager也没有显示Fragments?这是什么原因呢?问题出在它们使用了相同的布局吗?无论如何,它不是一个不同的对象吗?
Activity中这两个Fragment共享的布局如下:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.PagerTitleStrip
        android:id="@+id/search_mapping_pager_title_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33b5e5"
        android:paddingBottom="4dp"
        android:paddingTop="4dp"
        android:textColor="#fff" />

</android.support.v4.view.ViewPager>

两个片段都以相同的方式实例化ViewPager:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_search_mapping,
            container, false);

    mSectionsPagerAdapter = new SectionsPagerAdapter(mActivity
            .getSupportFragmentManager());
    mViewPager = (ViewPager) view.findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    return view;
}

编辑:更多代码展示我的SectionsPagerAdapter

public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = new SuperclassFragment();
        Bundle args = new Bundle();
        args.putInt(SuperclassFragment.ARG_SECTION_NUMBER, position + 1);
        fragment.setArguments(args);
        return fragment;
    }

    ...

}

你有什么建议可以帮助我找到这个bug的原因吗?如果需要的话,我当然可以在这里加入更多的代码。


你应该将Viw=ewPage放在Linear/Relative Layout之下。另外,你能否把SectionsPagerAdapter代码贴出来,因为它的getItem函数很有意思。 - Amit
用Linear/Relative Layout没问题,我想。我已经放了SectionsPagerAdapter的代码。可能问题就是他们使用相同的FragmentManager实例吗? - Terry
我认为,代码中的这一行 Fragment fragment = new SuperclassFragment(); 存在问题。当 View Pager 调用 getItem 方法时,你返回的是 SuperclassFragment,它是一个父类,因此 View Pager 不知道要渲染哪个具体的子类 Fragment,于是它会使用在 classpath 中找到的第一个 Fragment,但我不确定。 - Amit
不,它不是一个抽象类,如果你是这个意思的话。名称有点误导,但它只是一个普通的public static class SuperclassFragment extends Fragment,基本上与使用ADT Eclipse的Activity向导生成ViewPager导航时获得的DummySectionFragment相同。 - Terry
3个回答

1
我通过将ViewPagers直接放入Activity的布局中而不是放入Fragments中来自己解决了这个问题。
然后,Activity的XML布局如下所示:
...
<LinearLayout 
    android:id="@+id/search_fragment_layout"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:orientation="horizontal">

    <android.support.v4.view.ViewPager
        android:id="@+id/objectPager"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.5"
        android:layout_margin="16dp" >
        <android.support.v4.view.PagerTitleStrip
            android:id="@+id/object_pager_title_strip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#33b5e5"
            android:paddingBottom="4dp"
            android:paddingTop="4dp"
            android:textColor="#fff" />
    </android.support.v4.view.ViewPager>

    <android.support.v4.view.ViewPager
        android:id="@+id/actionPager"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.5"
        android:layout_margin="16dp" >
        <android.support.v4.view.PagerTitleStrip
            android:id="@+id/action_pager_title_strip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#33b5e5"
            android:paddingBottom="4dp"
            android:paddingTop="4dp"
            android:textColor="#fff" />
    </android.support.v4.view.ViewPager>

</LinearLayout>
...

在Activity本身中使用它实际上创建了2个不同的ViewPager对象,两者都按预期显示其片段。

我仍然不确定是什么导致了这个错误。如果有人提出一个好的解释,我愿意接受它作为答案。


1
FragmentPagerAdapter依赖于ViewPager id/Page Item id的组合来检查页面项是否需要被实例化(请参阅FragmentPagerAdapter.instantiateItem函数)。如果您将ViewPager放入片段中,则View Pager的两个实例最终将具有相同的id,而由于页面位置是页面的默认id,因此第二个ViewPager的页面永远不会被实例化。
解决方法是通过编程方式设置ViewPager id:
viewPager.setId(myID++);
或者在适配器上覆盖getItemId,使不同ViewPager的项目id不同。

0
通过将ViewPager放置在Fragment的布局中,您正在尝试在Fragment内添加一个子Fragment。嵌套Fragment仅从4.2版本开始支持,并且现在也已添加到Support Library中。
为了支持在Fragment中使用ViewPager,您需要实现自己的PagerAdapter版本。来自SO帖子之一,
“完全可以将ViewPager放置在Fragment中,只要ViewPager的内容本身不包含片段。由于Android Support包提供的PagerAdapter的具体实现使用片段,因此您必须自己编写无片段的PagerAdapter以将ViewPager放入片段中。”
以下是描述问题和可能解决方案的几篇文章 为什么不能在Fragment中使用ViewPager?实际上是可以的 Fragment内部的ViewPager问题

这对我的问题没有帮助。显然,在一个Fragment中放置一个带有Fragments的ViewPager是可行的。第一个完美地工作了,只有第二个不起作用,我不清楚为什么会出现这种情况。 - Terry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接