PagerTabStrip + ViewPager

Maybe you already know about ViewPager and are using something like ViewPagerIndicator by JakeWharton for indicating the title. Did you know that there is something doing that in the support library? If you use it, it looks like this:

Now how do you use this? First you need to set up your ViewPager. If you already know how to do that, please skip this part.

Setting up ViewPager

ViewPager is the Component that allows us swiping through Pages to the left and right. The best way to use a ViewPager is with Fragments. (If you do not know about Fragments yet, search for it on Google and read a little bit about it.)

To implement the ViewPager we need to do three things:

  1. Add a ViewPager to the layout in your .xml file that you set in the Activity
  2. Implement a PagerAdapter (in our case a FragmentPagerAdapter) and use it in the ViewPager
  3. Implement the content of the PagerAdapter (in our case Fragments)
    Let us look at the code to add the ViewPager to the layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>

So we use the ViewPager from the support library (make sure you have the support library in your libs folder or in the pom.xml if you use Maven).

Next we have to get the ViewPager, implement the Adapter and the Fragment. Here I implemented it in MainActivity.java:

package ch.pboos.android.sample.viewpager;
 
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
public class MainActivity extends FragmentActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        viewPager.setAdapter(new SampleFragmentPagerAdapter());
    }
 
    public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
        final int PAGE_COUNT = 5;
 
        public SampleFragmentPagerAdapter() {
            super(getSupportFragmentManager());
        }
 
        @Override
        public int getCount() {
            return PAGE_COUNT;
        }
 
        @Override
        public Fragment getItem(int position) {
            return PageFragment.create(position + 1);
        }
    }
 
    public static class PageFragment extends Fragment {
        public static final String ARG_PAGE = "ARG_PAGE";
 
        private int mPage;
 
        public static PageFragment create(int page) {
            Bundle args = new Bundle();
            args.putInt(ARG_PAGE, page);
            PageFragment fragment = new PageFragment();
            fragment.setArguments(args);
            return fragment;
        }
 
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mPage = getArguments().getInt(ARG_PAGE);
        }
 
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_page, container, false);
            TextView textView = (TextView) view;
            textView.setText("Fragment #" + mPage);
            return view;
        }
    }
}

As well we need the following xml which is used for the PageFragment:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center" />

There is some explanation needed here.

  1. onCreate()
    We set up the ViewPager to use our PagerAdapter.
  2. SampleFragmentPagerAdapter
    The adapter provides the following functions for ViewPager.
  • getCount(): How many pages are there
  • getItem(): Create the page.
  1. PageFragment
    The content for each Page. We just set it up with a page number and content.
    Note here that we use Arguments instead of just setting local variables. This is the way you should provide information to Fragments so they work correctly when being destroyed and recreated by the system.
    Now we the whole PagerAdapter should be working correctly. But how to get the nice headers? Continue reading.

Setting up PagerTabStrip

As headers we use PagerTabStrip. You can as well use PagerTitleStrip but I think PagerTabStrip looks better. To add those headers we need to change the activity_main.xml like the following:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <android.support.v4.view.PagerTabStrip
        android:id="@+id/pager_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#000"
        android:paddingBottom="4dp"
        android:paddingTop="4dp"
        android:textColor="#fff" />
 
</android.support.v4.view.ViewPager>

So you see we added the PagerTabStrip inside the ViewPager. You can play around with the colors if you like. If you just do this you will see the header, but no text. Because we did not tell the ViewPager yet what the titles are for each page. To do this we need to override getPageTitle(int position):

        public CharSequence getPageTitle(int position) {
            return "Page " + (position + 1);
        }

Once we implemented this we should see the titles correctly.

How to use with ActionBarSherlock or Maven

Problem with ActionBarSherlock and Maven is that there is only the old support library used/available. So using ActionBarSherlock for example we will not be able to find PagerTabStrip. You could just use PagerTitleStrip, but that might not be good enough for you. So what can you do? You can copy paste the code from PagerTitleStrip to your own source code. To do this without getting errors, do the following:

  1. Copy PagerTitleStrip.java and PagerTabStrip.java from $ANDROID_HOME/extras/android/support/v4/src/java/android/support/v4/view/ to $YOUR_PROJECT/src/android/support/v4/view/
  2. Copy PagerTitleStripIcs.java from $ANDROID_HOME/extras/android/support/v4/src/ics/android/support/v4/view/
  3. Refactor ->rename inside eclipse/intellij idea to call them PagerTabStrip2, PagerTitleStrip2 and PagerTitleStripIcs2.

In the xml and java files use the same code as above, but with the PagerTabStrip2 instead of PagerTabStrip.