Terry
Terry

Reputation: 14897

Android: 2 Fragments sharing same ViewPager XML layout

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.

Upvotes: 3

Views: 2621

Answers (3)

Sergey Aldoukhov
Sergey Aldoukhov

Reputation: 22744

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.

Upvotes: 1

Amit
Amit

Reputation: 1385

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

Upvotes: 0

Terry
Terry

Reputation: 14897

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.

Upvotes: 1

Related Questions