Android PagerTabStrip and PagerTitleStrip with ViewPager

Note: This post is sort of a continuation of my previous post on ViewPager and its related pager adapters with tabs.

When working with ViewPager we most likely include action bar tabs and integrate them with their corresponding screens in the ViewPager. Action bar tabs works great but just incase if you prefer scrollable tabs and want to use them over action bar tabs then there are two ways to achieve that:

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

Both of them are supposed to be used as a child view of the ViewPager widget in the XML layout resource. So here’s how a ViewPager with a PagerTabStrip in it would look like in the layout file:

<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_tab_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33b5e5"
        android:textColor="#fff"
        android:paddingTop="5dp"
        android:paddingBottom="5dp" />


</android.support.v4.view.ViewPager>

Similarly, this is how the layout code for a ViewPager with a top-aligned PagerTitleStrip would be like:

<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.PagerTitleStrip
        android:id="@+id/pager_title_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33b5e5"
        android:textColor="#fff"
        android:paddingTop="5dp"
        android:paddingBottom="5dp" />


</android.support.v4.view.ViewPager>

Not much of a difference in the code between both the versions. Only the tag name and ID got changed.

Now when you test this code in your emulator or a physical android device, then you’ll notice a blue strip at the top of the view pager. You’ll be able to navigate through the pager screens but there won’t be any text in the pager strip unless they’re specified in the getPageTitle() method of the pager adapter implementation which should return the title for specific pages. The method implementation should look something like this:

@Override
public CharSequence getPageTitle(int position) {
    switch (position) {
        case 0:
            return "Tab One";
        case 1:
            return "Tab Two";
        case 2:
            return "Tab Three";
    }

    return null;
}

The method should return null which would indicate no title for that particular page. Although I used switch block you could also write the same code in another way by using arrays and returning the corresponding title by using the position argument as the array index.

Code Sample

For the sake of quickly testing `PagerTabStrip` I’ve put together some code. Here’s the Activity bit:

public class MainActivity extends Activity {

    CustomPagerAdapter mCustomPagerAdapter;
    ViewPager mViewPager;

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

        mCustomPagerAdapter = new CustomPagerAdapter(getFragmentManager(), this);

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mCustomPagerAdapter);
    }

    class CustomPagerAdapter extends FragmentPagerAdapter {

        Context mContext;

        public CustomPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            mContext = context;
        }

        @Override
        public Fragment getItem(int position) {

            // Create fragment object
            Fragment fragment = new DemoFragment();

            // Attach some data to the fragment
            // that we'll use to populate our fragment layouts
            Bundle args = new Bundle();
            args.putInt("page_position", position + 1);

            // Set the arguments on the fragment
            // that will be fetched in the
            // DemoFragment@onCreateView
            fragment.setArguments(args);

            return fragment;
        }

        @Override
        public int getCount() {
            return 3;
        }

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

    class DemoFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Inflate the layout resource that'll be returned
            View rootView = inflater.inflate(R.layout.fragment_demo, container, false);

            // Get the arguments that was supplied when
            // the fragment was instantiated in the
            // CustomPagerAdapter
            Bundle args = getArguments();
            ((TextView) rootView.findViewById(R.id.textView)).setText("Page " + args.getInt("page_position"));

            return rootView;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.gesture, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

This is how the res/layout/activity_main.xml should be like:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:id="@+id/relativeLayout">

    <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_title_strip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#33b5e5"
            android:textColor="#fff"
            android:paddingTop="5dp"
            android:paddingBottom="5dp" />

    </android.support.v4.view.ViewPager>

</RelativeLayout>

Finally here’s the res/layout/fragment_demo.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textView" />
</LinearLayout>

Go ahead and test your app now! Play with the view pager and its top-aligned pager strip. You can also customize the PagerTabStrip programatically. Feel free to go through the public methods here.

PagerTabStrip vs PagerTitleStrip – the Difference

Although both of them are quite similar there are certain differences which makes PagerTabStrip superior compared to the other one and hence most likely you’ll always want to use it over the other.

PagerTitleStrip only indicates the section we’re in through the title names. On the contrary, PagerTabStrip not only indicates the section name but also has the tab indicator (bottom border) that depicts the active tab. Also PagerTabStrip is interactive which means you can click on the tabs to switch among screens while you cannot do that with PagerTitleStrip (major limitation IMHO).

On going through the public methods for both in the docs, you’ll notice PagerTabStrip has marginally more methods or options to customize compared to PagerTitleStrip.

I came across this plugin called ViewPagerIndicator that allows you to customize your pager strip in so many different ways. You can even replicate the google play scrollable tabs with this plugin.

Hope that helps!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

10 thoughts on “Android PagerTabStrip and PagerTitleStrip with ViewPager”

  1. This line has a conflict:
    mCustomPagerAdapter = new CustomPagerAdapter(getFragmentManager(), this);

    getFragmentManager() returns a fragment manager from android.app and the adapter seems to expect (or the rest of the app seems to expect) one from support lib but the other components aren’t compatible with this in one way or the other. How to fix this?

  2. Great tutorial! Thank you so much!
    The only thing I would’ve added is screenshots or something to depict the code or what we should get eventually. It’d be great if you could add that.
    Thanks again!

  3. Hi
    Thanks for your tutorials
    I’m new developer I just copy-pasted codes the only error is at line 76 (R.menu.gesture)what is this id ?
    please explain if possible.
    thank you again.

    1. It is the menu file which I haven’t created in this post. I’ll probably upload the code somewhere on Github so that people can use that as a reference (and even download).

      1. Hi
        Could you please say what exactly it(i.e. gesture) does or if can it be removed.
        thanks for your answers.

  4. The code is not working on the latest Android Studio (version 2.x).
    Here is a working code.

    public class MainActivity extends FragmentActivity {

    ViewPager mViewPager;

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

    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(new CustomPagerAdapter(getSupportFragmentManager()));
    }

    class CustomPagerAdapter extends FragmentPagerAdapter {

    public CustomPagerAdapter(android.support.v4.app.FragmentManager fm) {
    super(fm);
    }

    @Override
    public Fragment getItem(int position) {

    // Create fragment object
    Fragment fragment = new DemoFragment();

    // Attach some data to the fragment
    // that we’ll use to populate our fragment layouts
    Bundle args = new Bundle();
    args.putInt(“page_position”, position + 1);

    // Set the arguments on the fragment
    // that will be fetched in the
    // DemoFragment@onCreateView
    fragment.setArguments(args);
    return fragment;
    }
    @Override
    public int getCount() {
    return 3;
    }
    @Override
    public CharSequence getPageTitle(int position) {
    return “Page ” + (position + 1);
    }
    }

    class DemoFragment extends Fragment {

    public DemoFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_demo, container, false);
    Bundle args = getArguments();
    ((TextView) rootView.findViewById(R.id.textView)).setText(“Page ” + args.getInt(“page_position”));
    return rootView;
    }
    }
    }

Leave a Reply to Weeber Cancel reply

Your email address will not be published. Required fields are marked *