The Android support library offers a great UI component for horizontal scrolling pages: The ViewPager. Over the last iterations of the support library more and more functionality has been added to the ViewPager silently. For that reason I decided to study the various features of the ViewPager more closely. This will be a series of articles covering several of these features.
According to the documentation of the ViewPager the implementation and API of the class may change in future releases. Therefore also this blog posting may not be up-to-date if you are reading this a long time after the published date. Check the documentation if some of the examples may not work anymore as I described them here.
The ViewPager is a ViewGroup that displays by default one page at a time. The user can switch between these pages by swiping horizontally. A PagerAdapter dynamically provides these pages which can be just views or fragments. However the ViewPager is not an AdapterView like the ListView or the GridView. Therefore you need to implement a specific adapter class in order to use the ViewPager class.
The following video shows a ViewPager with different colored pages:
Adapter using fragments
The easiest way to write an adapter for a ViewPager is to use fragments and let your adapter implementation extend the FragmentPagerAdapter class. You only need to implement getItem(int position) to return a fragment for the page at the given position and getCount() to return the number of pages to display.
The following implementation shows the FragmentPagerAdapter used for the video above:
Saving fragment states
When using a FragmentPagerAdapter and swiping through the pages the ViewPager may eventually have created fragments for all the pages. Depending on the number of pages this may need a large amount of memory just for holding all the offscreen pages. To solve this problem the support library offers the FragmentStatePagerAdapter class. This adapter will destroy fragments not visible to the user when needed. Whenever this happens the adapter saves the fragment's current state using onSaveInstanceState(Bundle outState) of the fragment class to restore it when the fragment for this page gets recreated.
Implementing an adapter extending the FragmentStatePagerAdapter is exactly the same as when using the FragmentPagerAdapter class. Just your fragment needs to take care of saving its state when getting destroyed. Take a look at the documentation for an example on how to retain the state of a fragment.
Adapter using views
You can also use the ViewPager with only View objects as pages if using fragments isn't an option for you. It's a bit more tricky to implement the adapter as you'll have to directly extend the PagerAdapter class.
The following example creates an adapter that shows a number of different colored pages like the FragmentPagerAdapter implementation above.
As you can see you need to write some boilerplate code to add and remove the views to the pager. I published a simple ViewPagerAdapter class on GitHub that does all this for you so that you don't need to write much more code than when using fragments: