Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Sliding Between Views with a ViewPager

Author: Ian Darwin
Published? true -- FormatLanguage: W

Problem:

You have a variety of similar view pages and want the user to be able to swipe or slide sideways to navigate from one to the next.

Solution:

Use a ViewPager as the layout manager, and implement a FragmentAdapter to create and set up an instance of your Fragment subclass for each of the pages (they must be Fragments, not Activities, as they are controlled directly by your Activity class).

Discussion:

ViewPager was added after Honeycomb (since it requires Fragments), but is in the support libraries back to v4, so you can use it almost anywhere. As with all things involving the support library, be sure to either pick all the support library versions of API or the non-support version, don't try to mix and match.

The Activity that is to manage the multiple pages should extend FragmentActivity, since it has to manage Fragments. Its onCreate will typically do something like the following (each page will have the information for one country):

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		List<Fragment> fragments = getFragments();
		CountryPageAdapter pagerAdapter = 
		new CountryPageAdapter(getSupportFragmentManager(), fragments); 
		ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
		pager.setAdapter(pagerAdapter);
	}

The layout file can be as simple as just a ViewPager:

<android.support.v4.view.ViewPager 
	 xmlns:android="http://schemas.android.com/apk/res/android" 
	 android:id="@+id/viewpager"	 
	 android:layout_width="fill_parent"
 	 android:layout_height="fill_parent" />

The getFragments() method (or whatever you choose to call it) needs to instantiate the Fragments and configure them. You are not supposed to use constructor arguments when instantiating Fragments, so the code is a bit more involved that it might otherwise be, but we are passing the initialization information (for now, just the country name) into the Fragment via a Bundle.

	private List<Fragment> getFragments() {
		List<Fragment> frags = new ArrayList<Fragment>();
		frags.add(prepareFragment("Canada"));		
		frags.add(prepareFragment("U.S.A."));		
		frags.add(prepareFragment("Mejico"));		
		return frags;
	}

	/**
	 * Create and set up one CountryFragment.
	 * @param name Country name.
	 */
	Fragment prepareFragment(String name) {
		CountryFragment cf = new CountryFragment();
		Bundle args = new Bundle();
		args.putString(CountryFragment.COUNTRY_NAME, name);
		cf.setArguments(args);
		return cf;
	}

The Fragment class(es) will have their own layout file which, as in all Fragments, you are responsible for inflating in onCreateView(); ours has just a TextField that we populate with data from the Bundle, all in the Fragment's onCreateView() method:

@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
		Bundle savedInstanceState) {
		String name = getArguments().getString(COUNTRY_NAME);
		this.name = name;
		View v = inflater.inflate(R.layout.country_fragment, container, false);
		TextView messageTextView = (TextView) v.findViewById(R.id.countryNameView);
		messageTextView.setText(name);
		return v;
	}

Lastly, the Adapter class has to provide at least getCount() and getItem(int) methods; to avoid having to write all the other Adapter methods you should extend FragmentPagerAdapter, as our CountryPageAdapter does. In our example, the getItem(int) simply returns the index by number from the List of Fragments created in the Activity's onCreate and passed into the CountryPageAdapter constructor. This code is trivial so we don't show it, but it's in the online example for this recipe.

Run the application and you can swipe sideways between pages. It's then obvious how to extend the Fragment view layout to contain more View objects and its onCreateView method to populate them.

Download:

The source code for this project is in the Android Cookbook repository at http://github.com/IanDarwin/Android-Cookbook-Examples, in the subdirectory ViewPagerDemo.
No records found.