How to Use ViewPager for Navigating between Fragments (With TabLayout)

Making Fragments Scroll Nicely

Kyros Chow
3 min readJan 12, 2018

ViewPager is a layout manager that allows the user to scroll left and right to navigate through multiple Fragments with a sliding animation. An adapter handles all the transactions between different Fragments. This way, FragmentTransaction.replace() does not have to be called every time the user scrolls. After the tutorial there will be a few tips to avoid common errors and enhance the user experience if your code does not work as expected. You can find the source code of this project here.

Step 1: Put a ViewPager widget in your xml layout. I put the widget in activity_main.xml and assigned its id to be view_pager.

activity_main.xml

Step 2: Set up the child Fragments you would like to display. I made 3 child Fragments, calling them ChildFragment1, ChildFragment2, and ChildFragment3. Remember to have them extend support.v4.app.fragment. Now make layouts for all three of the Fragments. I call them child_fragment_1_layout, child_fragment_2_layout, and child_fragment_3_layout. For simplicity, I will put one Button in each layout (with ids button_1, button_2, and button_3 respectively) and have them make a Toast when they are clicked. Override the onCreateView() method and inflate the layouts. Wire up the buttons to display a different Toast.

3 different child fragments (replace with your own fragments)
3 layouts for each child fragment (replace with your own layouts)
Code in ChildFragment1. For ChildFragment2 and ChildFragment3, simply replace all the 1s with 2s and 3s.

Step 3: Make an adapter for the ViewPager. You will have to extend either theFragmentPagerAdapter or the FragmentStatePagerAdapter. For this tutorial we will use the FragmentPagerAdapter . The difference between the two can be found here. After extending the FragmentPagerAdapter, you will need to call super(FragmentManager) in your constructor and implement the methods getItem(position) and getCount(). The getItem(position)method is used to return the fragment at the corresponding position, ordered from left to right. So ChildFragment1 would be at position 0, ChildFragment2 would be at position 1, and ChildFragment3 would be at position 2. The getCount() method is to count how many Fragments there are to display, and in this case, there are 3.

Step 4: Now find your ViewPager in MainActivity and call the setAdapter() method and pass in your custom adapter. If you are doing this in another Fragment (Nested Fragments), you will have to pass in getChildFragmentManager() in the argument of your adapter instead. Now your ViewPager is all set!

Using ViewPager with TabLayout

Step 5: You can display tabs with ViewPager really easily. (You can use ViewPagerTitleStrip and ViewPagerTabStrip as well.) Include a TabLayout in your activity_main.xml. I will give it an id tab_layout. Remember to change the constraint of your ViewPager so it does not block the TabLayout.

Step 6: Go to MainActivity and find the TabLayout. Then call setupWithViewPager() and pass in your ViewPager as the argument.

Step 7: Finally, go to your adapter and change the title of each Fragment. Override the getPageTitle() method.

You can actually return SpannableStrings and change the style of the text. If you want icons in your title, check out ImageSpan.

The result should look like this:

Avoiding Errors and Enhancing the User Experience

Q: Why does an Exception occur when I tried to change something in the 3rd Fragment from the 1st Fragment?
A: By default, ViewPager only loads its adjacent Fragments (one to the left and one to the right), and if you tried to change the unloaded Fragments there will be an error.

Q: While scrolling within the ViewPager I noticed a small amount of input delay and sometimes the Views suddenly pop into the page instead of sliding over. What can I do?
A: There are 2 reasons that this may occur. First you may be using too many Fragments in your FragmentPagerAdapter. Consider using a FragmentStatePagerAdapter instead. It is a better option if there is a large number of child Fragments. Second, you are probably loading too many views in your fragment. There are 3 ways to fix that problem. First you can load the content in the Views after the ViewPager is idle. You can listen for that change with the ViewPager.OnPageChangeListener. Second, you can increase the default amount of pages loaded with the ViewPager.setOffScreenPageLimit() method. Finally, you should always use a RecyclerView instead of a ListView in your child Fragments because it reuses cells as the user scrolls up and down.

--

--