3

I have an Activity with a layout that contains 2 Fragments next to each other. In each Fragment, I have a ViewPager. Since I need both Fragments to look the same way, I use the same layout XML for both, which contains a ViewPager.

Now when I test the app, only the ViewPager of the first Fragment seems to work. The second Fragment shows a PagerTitleStrip, and I can flip through it, but it doesn't show the Fragments in the ViewPager.

Why isn't the second ViewPager showing the Fragments too? What is causing this? Is the problem that they use the same layout? Isn't it a different Object anyway?

The layout that the 2 Fragments in the Activity share looks like this:

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

Both Fragments instantiate the ViewPager the same way:

@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;
}

EDIT: More code showing my 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;
    }

    ...

}

Any tips where I should look for the cause of the bug? I can of course include more code here if necessary.

Terry
  • 14,529
  • 13
  • 63
  • 88
  • You should put Viw=ewPage under Linear/Relative Layout. Also, can you please put SectionsPagerAdapter code as it is interesting to see getItem function – Amit Apr 03 '13 at 17:51
  • With the Linear/Relative Layout you're right, I think. I have put the code of SectionsPagerAdapter. May it be that the problem is that they use the same `FragmentManager` instance? – Terry Apr 03 '13 at 17:59
  • I think, line Fragment fragment = new SuperclassFragment(); is problem. View Paget will call getItem method, at this time, you are returning SuperclassFragment. Its a parent class and so View Pager does not know which fragment to render and it will use the first fragment it find in classpath, I am not sure though – Amit Apr 03 '13 at 18:03
  • No, it's not an abstract class, if you meant that. The name is a bit misleading, but it's just a normal `public static class SuperclassFragment extends Fragment`, it's basically the same like the `DummySectionFragment` you get if you generate a ViewPager navigation with ADT Eclipse's Activity wizard. – Terry Apr 03 '13 at 18:11

3 Answers3

1

I solved the problem myself by not putting the ViewPagers into Fragments, but putting them directly into the layout of the Activity.

The XML layout of the Activity then looks like this:

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

Using it in the Activity itself actually creates 2 distinct ViewPager objects, and both show their Fragments as expected.

I'm still not sure what caused the bug. If someone comes up with a good explanation, I'm willing to accept that as an answer.

Terry
  • 14,529
  • 13
  • 63
  • 88
1

FragmentPagerAdapter relies on a combination of ViewPager id/Page Item id to check if the page item needs to be instantiated (see FragmentPagerAdapter.instantiateItem function). If you place your ViewPager into a fragment, both instances of the View Pager will end up having the same id, and since page position is the default id for the page, pages for the second ViewPager are never instantiated.

The workaround is ether to set ViewPager id programmatically:
viewPager.setId(myID++);
or override getItemId on your adapter so item id's are different for different ViewPager's.

Sergey Aldoukhov
  • 22,316
  • 18
  • 72
  • 99
0

By putting ViewPager inside Fragment's layout, you are trying to add a child fragment inside a fragment. Nested fragment is only supported from 4.2 onwards and now its added in Support Library too.

In order to support View Pager insider a fragment, you need to implement your own version of PagerAdapter. From one of the SO post,

It is perfectly possible to put a ViewPager inside a Fragment, so long as the contents of the ViewPager do not themselves contain fragments. Since the concrete implementations of PagerAdapter supplied by the Android Support package use fragments, you have to roll your own fragment-less PagerAdapter to put the ViewPager in a fragment.

Below are few post which describe the problem and possible solution

Why it is not possible to use ViewPager within a Fragment? It actually is

ViewPager inside fragment issue

Community
  • 1
  • 1
Amit
  • 1,365
  • 8
  • 15
  • This doesn't help me with my problem. Apparently, it is indeed possible to put a ViewPager _with_ Fragments inside a Fragment. For the first one it perfectly worked, just the second one won't work, and it is not clear to me why this behavior. – Terry Apr 05 '13 at 09:25