In this post I’m going to show you an example usage of ViewPager in conjunction with ActionBarSherlock tabs.
The final result should look like this:
1. Add the ActionBarSherlock library to your project. (Here’s a short tutorial on how to integrate ABS with a project, in case you need a refresh on this)
2. Change the AndroidManifest file of your project to use one of the predefined themes by ABS:
<application //.... android:theme="@style/Theme.Sherlock.Light" > //..... </application>
Note that using ActionBarSherlock requires you to use one of these themes: Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or any other derivate, otherwise a RuntimeException exception will be thrown.
3. Create the MainActivity.java:
public class MainActivity extends SherlockFragmentActivity { private ActionBar actionBar; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.pager); viewPager.setOnPageChangeListener(onPageChangeListener); viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager())); addActionBarTabs(); } private ViewPager.SimpleOnPageChangeListener onPageChangeListener = new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { super.onPageSelected(position); actionBar.setSelectedNavigationItem(position); } }; private void addActionBarTabs() { actionBar = getSupportActionBar(); String[] tabs = { "Tab 1", "Tab 2", "Tab 3" }; for (String tabTitle : tabs) { ActionBar.Tab tab = actionBar.newTab().setText(tabTitle) .setTabListener(tabListener); actionBar.addTab(tab); } actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); } private ActionBar.TabListener tabListener = new ActionBar.TabListener() { @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { } }; }
Another requirement in order to use Sherlock library is that your activity should extend from SherlockFragmentActivity, and this is what MainActivity does first.
Then it takes a reference to the ViewPager and sets the OnPageChangedListener and the PagerAdapter (implementation will be shown below):
viewPager = (ViewPager) findViewById(R.id.pager); viewPager.setOnPageChangeListener(onPageChangeListener); viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
In short, a ViewPager is a layout manager that allows you to swipe left and right through pages of data.
It needs to be supplied with an implementation of PagerAdapter in order to generate the pages that the view shows.
Just below the initialization of ViewPager the action bar tabs are added:
private void addActionBarTabs() { actionBar = getSupportActionBar(); String[] tabs = { "Tab 1", "Tab 2", "Tab 3" }; for (String tabTitle : tabs) { ActionBar.Tab tab = actionBar.newTab().setText(tabTitle) .setTabListener(tabListener); actionBar.addTab(tab); } actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); }
For every string in the tabs[] array a new ActionBar.Tab is created and added to the ActionBar.
4. And the layout of MainActivity, R.layout.activity_main, which simply defines the ViewPager container.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
5. The implementation of ViewPagerAdapter.java:
public class ViewPagerAdapter extends FragmentStatePagerAdapter { private final int PAGES = 3; public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new TabFragment1(); case 1: return new TabFragment2(); case 2: return new TabFragment3(); default: throw new IllegalArgumentException("The item position should be less or equal to:" + PAGES); } } @Override public int getCount() { return PAGES; } }
The PagerAdapter helps represent each page as a Fragment.
By extending FragmentStatePagerAdapter two methods should be overrided:
getCount() – which returns the total number of pages the ViewPager will have, and
getItem() – which returns a new fragment for each page.
6. Bellow follows the fragment classes used for representing each page. The minimalistic implementation is to extend from SherlockFragment, and provide a view for the fragment itself.
TabFragment1.java:
public class TabFragment1 extends SherlockFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_tab_1, container, false); } }
TabFragment2.java:
public class TabFragment2 extends SherlockFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_tab_2, container, false); } }
TabFragment3.java:
public class TabFragment3 extends SherlockFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_tab_3, container, false); } }
7. And their corresponding layout files, which in this particular example have just a single TextView element.
fragment_tab_1.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Fragment tab 1" /> </RelativeLayout>
fragment_tab_2.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Fragment tab 2" /> </RelativeLayout>
fragment_tab_3.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Fragment tab 3" /> </RelativeLayout>
