How to add a Fragment inside a ViewPager using Nested Fragment (Android 4.2)

sabadow picture sabadow · Nov 14, 2012 · Viewed 63.2k times · Source

I have a ViewPager with three Fragments, each one shows a List (or Grid).

In the new Android API level 17 (Jelly Bean 4.2), one of the features is Nested Fragments. The new functionality description says:

if you use ViewPager to create fragments that swipe left and right and consume a majority of the screen space, you can now insert fragments into each fragment page.

So, if I understand right, now I can create a ViewPager with Fragments (with a button inside for example) inside, and when user press the button show another Fragment without loose the ViewPager using this new feature.

I've expended my morning trying to implement this several different ways, but I can´t get it working... Can somebody add a simple example of how to implement this?

PS: I'm only interested in doing at this way, with getChildFragmentManager to learn how works.

Answer

Marco RS picture Marco RS · Nov 15, 2012

Assuming you have created the correct xml layouts. It is now very simple to display fragments in a ViewPager that is hosted by another Fragment.

The following is a parent fragment that displays child fragments:

class ParentViewPagerFragment : Fragment() {

  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val root = inflater.inflate(R.layout.fragment_parent_viewpager, container, false)

    val viewPager = root.findViewById(R.id.viewPager) as ViewPager
    // Important: Must use the child FragmentManager or you will see side effects.
    viewPager.adapter = MyAdapter(childFragmentManager)

    val tabStrip = root.findViewById<TabLayout>(R.id.pagerTabStrip)
    tabStrip.setupWithViewPager(viewPager)

    return root
  }

  class MyAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) {

    override fun getCount(): Int = 4

    override fun getItem(position: Int): Fragment {
      val args = Bundle().apply { putInt(ChildFragment.POSITION_KEY, position) }
      return ChildFragment.newInstance(args)
    }

    override fun getPageTitle(position: Int): CharSequence = "Tab $position"
  }

  companion object {
    val TAG: String = ParentViewPagerFragment::class.java.name
  }
}

It is important to use Fragment.getChildFragmentManager() when instantiating the FragmentPagerAdapter. Also note that you cannot use Fragment.setRetainInstance() on the children fragments or you'll get an exception. The imports were omitted for brevity.

Source code can be found at: https://github.com/marcoRS/nested-fragments