ViewPager / ViewPagerIndicator

ViewPager – Part 1

Important note: There is a more recent article which covers a newer version of ViewPagerIndicator. Please refer to this in conjunction with this article

Richard Hyndman recently wrote on his personal blog and the Android Developers blog about the ViewPager functionality which has been added to the Android Compatibility Library. Jake Wharton has published his ViewPagerIndicator which works in conjunction with ViewPager and gives some pretty slick behaviour for surprisingly little effort. In this article, we’ll have a look at how to use both of these in a project.

The following instructions are for Eclipse Indigo, with EGit 1.0.0 and ADT12. If you are using versions which differ from these, then wording and the flow may be different to this.

First let’s retrieve and build Jake’s ViewPagerIndicator library.

If you have a system set up to correctly build Android projects using Maven, including having the necessary Android platforms in your Maven repository, then feel free to import the project by selecting “File|Import…” from the menu, then expand “Maven”, select “Check out Maven Projects from SCM”, then checking out “https://github.com/JakeWharton/Android-ViewPagerIndicator.git”. If you’ve got Maven set up correctly, then I’m sure that you know how to import a project.

If you haven’t got Maven set up for Android development, then we can bypass Maven (as it can be tricky to get set up). First select “File|Import…” from the menu, then expand “Git”, select “Projects from Git”, and click “Next >”. Next click on “Clone…”, enter “https://github.com/JakeWharton/Android-ViewPagerIndicator.git” in the URI file, and click “Next >” twice. You will now be asked for a destination directory. This can be anything you like, just remember it because we’ll need it in a moment. Click “Finish”. Ensure that the repository that you just cloned is selected in the list, and click “Next >”. Select “Import as General Project” and click “Next >”, and then “Finish”. Now you need to import the library project by selecting “File|New|Project…|Android|AndroidProject” then “Next >”. Click “Create project from existing source”, then click “Browse…”, and navigate to the “library” folder inside the destination directory that you remembered from earlier, and click “OK”. Now click “Finish”.

You should now have the ViewPagerIndicator library source code downloaded, but if you did not go the Maven route, there will be a build error because there’s a dependency on the compatibility library which Maven would have resolved for us. Here ADT 12 comes to the rescue, right click on the project in the “Package Explorer” view then select “Android Tools|Add Compatibility Library…”. If there is still an error, right click on right click on the project in the “Package Explorer” view then select “Android Tools|Fix Project Properties”.

We should now have a copy of Jakes ViewPagerIndicator library which builds correctly. This may seem like a lot of work, but it really doesn’t take that long, and once you have it you can reuse it in other projects.

Let’s create a new Android 2.3.3 Project named “ViewPager” with a package name of “com.stylingandroid.viewpager”. Next we need to add the compatibility library support as we did before by right clicking the project, then selecting “Android Tools|Add Compatibility Library…”. Now we can add the ViewPagerIndicator library by right clicking the project and selecting “Properties|Android”, then clicking “Add…” in the Library section and selecting the ViewPagerIndicator library. Then click “OK”.

Now we’re ready to start coding. First we need to edit res/layout/main.xml and add our ViewPager and ViewPagerIndicator:

[xml]




[/xml]

This should be fairly obvious, we’re creating the two widgets and using a layout weight on the ViewPager to fill the available space. See the article on Layout Weights for more information on this. Jakes ViewPagerIndicator includes three different kinds of indicator. We’ll use TitlePageIndicator which is arguably the most complex to implement, but is pretty simple nonetheless.

Next we need to create a class named ViewPagerAdapter which extends android.support.v4.view.PagerAdapter which must implement com.jakewharton.android.viewpagerindicator.TitleProvider. The latter is a specific requirement for TitlePageIndicator:

[java] package com.stylingandroid.viewpager;

import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TextView;

import com.jakewharton.android.viewpagerindicator.TitleProvider;

public class ViewPagerAdapter extends PagerAdapter
implements TitleProvider
{
private static String[] titles = new String[] {
“Page 1”,
“Page 2”,
“Page 3”
};
private final Context context;

public ViewPagerAdapter( Context context )
{
this.context = context;
}

@Override
public String getTitle( int position )
{
return titles[ position ];
}

@Override
public int getCount()
{
return titles.length;
}

@Override
public Object instantiateItem( View pager, int position )
{
TextView v = new TextView( context );
v.setText( titles[ position ] );
((ViewPager)pager).addView( v, 0 );
return v;
}

@Override
public void destroyItem( View pager, int position, Object view )
{
((ViewPager)pager).removeView( (TextView)view );
}

@Override
public boolean isViewFromObject( View view, Object object )
{
return view.equals( object );
}

@Override
public void finishUpdate( View view ) {}

@Override
public void restoreState( Parcelable p, ClassLoader c ) {}

@Override
public Parcelable saveState() {
return null;
}

@Override
public void startUpdate( View view ) {}
}
[/java]

This is actually pretty straightforward, particularly if you are familiar with using Adapters for ListView, GridView, Spinner, etc.

We have a constructor which takes a single Context argument, declare a static array which will represent our page titles, and we implement the required methods from PagerAdapter and TitleProvider. The key ones are:

  • getTitle()
    This is the only methods from TitleProvider ad should return the title of page at he specified position. We return the relevant title from the titles array.
  • getCount()
    This returns the number of pages. In this case the size of our titles array.
  • instantiateItem()
    This creates the view for a given position. For a real application we would use a Fragment here, or inflate a layout, but to keep the example simple we create a TextView, set the text to the correct value from our titles array, and add it to the ViewPager.
  • destroyItem()
    This destroys a previously instantiated view. We simply remove it from the parent, and it will be garbage collected.

We use default implementations for the remaining required methods.

Finally we need to modify the onCreate() method of ViewPagerActivity to link the ViewPager to the ViewPagerAdapter, and TitlePageIndicator to the ViewPager:

[java] @Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.main );

ViewPagerAdapter adapter = new ViewPagerAdapter( this );
ViewPager pager =
(ViewPager)findViewById( R.id.viewpager );
TitlePageIndicator indicator =
(TitlePageIndicator)findViewById( R.id.indicator );
pager.setAdapter( adapter );
indicator.setViewPager( pager );
}
[/java]

If we now run this we can see things working:

Simple ViewPager with TitlePageIndicator
Simple ViewPager with TitlePageIndicator

I strongly urge you to try this out for yourself on a real device. A screenshot really does not give any indication of quite how smoothly this all works. It is worth noting that you can switch between pages by swiping left and right, or by tapping on the titles in the TitilePagerIndicator at the top.

The more perceptive reader will notice that this is quite similar (but not identical) to the swipey tabs in the new Android Market app.

In the next part of this article we’ll look at customising things.

Sorry if this article has been a little longer than usual, but I wanted to give a complete working example.

The source for this article can be found here. Once you checkout the code, you’ll need to manually add the compatibility library, and add ViewPagerIndicator as an Android library as we did at the start of this article.

© 2011 – 2012, Mark Allison. All rights reserved.

Copyright © 2011 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.

78 Comments

  1. Hi, thanks for those features, but i’ve got a question. I want to put some images in the view pager, but those images are from the internet, so i need to use the asynctask, but it doesn’t work, do you have any idea on how to do it ?

    1. Hi Peter,

      It’s difficult to work out why your code isn’t working without seeing it. Maybe you’re trying to load images on the UI thread.

      I can’t offer developer support on my blog, but I would suggest posting a specific question, including the relevant source code, to stackoverflow.com.

      1. It really depends on what you mean by “multiple screens”. Why not try out the code and see if it does what you require?

    2. I don’t seem to understand why I couldn’t connect the library project to the viewpager project. It is not showing on the list.

    1. Erm you might want to actually read my article. It explains how to use Jake Wharton’s ViewPagerIndicator – the very thing that you’re recommending to me.

      1. My bad.. Well, as I was skimming through it, your article said that “The more perceptive reader will notice that this is quite similar (but not identical) to the swipey tabs in the new Android Market app.”

        The thing is, Jake’s implementation really is identical to the new Android Market app in terms of functionality (tabs are swipable and the viewpager swipes with the tabs, just like in the market app), so I thought you were using a different swipey tabs implmentation.

  2. I’ve followed the instructions to a T (or at least I think I have…I’ve re-read 3 or 4 times to make sure) but I’m having an issue as soon as I make the ViewPagerAdapter class. It’s telling me “The import com.jakewharton cannot be resolved” (followed by many other errors that stem from this one). When I check the properties to make sure I had added the project we previously imported as a library, there is a red “X” instead of the green check mark that was there when I initially added it. After removing it and re-adding it multiple times, I’m unable to fix the problem. Any suggestions?

    1. Sorry, but I really don’t have the bandwidth to provide developer support. Writing the blog takes all of the time that I have available.

      Even if I was able to help, it would be impossible to diagnose without seeing your code to see what was wrong.

      I would suggest heading over to stackoverflow.com as the good folks there may be able to help. You’ll need to provide details of your implementation for anyone to be able to help, though.

      1. For reference for anyone else that might encounter this issue…your git directory needs to be in your workbench folder. Apparently eclipse doesn’t like it if it’s not.

        Mark…that might be a good update to this article, since you had initially said we can put it anywhere as long as we know where it is. The issue is detailed at the following link:
        http://stackoverflow.com/questions/5167273/in-eclipse-unable-to-reference-an-android-library-project-in-another-android-pr

        1. Hi, i have the same issue as you.But unfortunatelly i cant solve this problem.When I put my git directory to my workspace and then i create project from libary folder it makes error:Cant find manifest.xml.I would be wery gratefull if you could send me answer qickly :-).

      2. The pacakge name change might be a worthy update as well. His pacakge is now com.viewpagerindicator instead of com.jakewharton.android.viewpagerindicator

        1. I’m having the same problems… I changed the package name as described, but there doesn’t seem to be a TitleProvider interface anywhere in the source for that library….

          The closest class name is TitlePageIndicator and it’s not an interface… confused

  3. Hi,
    any idea why i’m having a ResourceNotFound exception when trying to use the CirclePageIndicator class ? res are embedded within the ViewPagerIndicator…

    12-19 23:48:56.268: E/AndroidRuntime(8577): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f050008
    12-19 23:48:56.268: E/AndroidRuntime(8577): at android.content.res.Resources.getValue(Resources.java:892)
    12-19 23:48:56.268: E/AndroidRuntime(8577): at android.content.res.Resources.getColor(Resources.java:622)
    12-19 23:48:56.268: E/AndroidRuntime(8577): at com.viewpagerindicator.CirclePageIndicator.(CirclePageIndicator.java:79)
    12-19 23:48:56.268: E/AndroidRuntime(8577): … 25 more

    1. The only obvious thing is to do a “clean” which will force a full rebuild. If that doesn’t work then I cannot help – I simply do not have the bandwidth to offer developer support. I would suggest going to StackOverflow.com when they may be able to help if you provide full details of your problem.

      1. ok, thx I understand.
        Just a last question : is there an easy way to create a ViewPagerIndicator-like that is just an horizontal thin line with a rectangle cursor moving inside to show the current position ?

  4. Hello, I’m asking a question a bit late here. I hope u will notice and reply to me.

    I’ve finished this tutorial (from part 1 to 3) successfully. After doing it with pleasure, I want to change to TabPageIndicator instead of TitlePageIndicator. So, I tried out. And it worked. But it didn’t have styled tabs. (Ah, sorry for my bad explanation. I’m bad at English.)

    What I changed to ur original code was,

    TitlePageIndicator to TabPageIndicator in the main activity. (also in the xml file)

    TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator);

    It runs successfully. What it missed is styles.

    So, Can you please tell me how can I get TabPageIndicator working?

    Thanks,
    Luke

  5. hello. after i follow your step, my problem when running is show in eclipse “android library projects cannot be launched”
    please help me.
    thanks.
    😀

  6. Hi i am facing a crucial problem here….

    In the ViewPagerAdapter class in

     public Object instantiateItem( View pager, int position ){

    LayoutInflater inflater = (LayoutInflater) pager.getContext()
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    int resId = R.layout.verlayout;

    ((ViewPager) pager).addView(view, 0);

    return view;
    }

    Like this i wrote, what ever layouts i gave in verlayout.xml is displaying correctly.

    But in my main activity oncreate function I need to get a layout/element in the verlayout.xml by findViewById but it always returns null in this oncreate method.
    How should i get a element/Layout in a view inside a viewpager from my oncreate method. The oncreate method i used is the same in this blog…

    Please help me

  7. Hi, nice tutorial!
    I’ve a question: when does the methods instatiateItem() and destroyItem() are called? One time on initialization or many times (after initialization) to free memory?

    1. My experience is that the current view and those either side are kept in memory at any one time. I’ve not done any major testing to prove that – it is simply what I have observed.

      1. Thank for your reply.

        I’ve another question: Take for instance this situation. Every page of my ViewPager has a ListView with almost 500 elements on each one. What is better to do in your opinion?

        a) Keep a list of ListView and ListAdapters. On instantiateItem() method simply check if that element exists, if not instatiate a new ListView and ListAdapter and keep it on the list.

        b) Keep only the adapters in the list.

        c) Don’t keep anything. Just realloc everything every time.

        (It’s a chat application)

        Thank you in advance.

  8. I don’t seem to understand why I couldn’t connect the library project to the viewpager project. It is not showing on the list.

  9. I am able to use this library, but problem is for example you have total 3 screens, left screen, middlescreen, and right screen, now you are on middle screen , if you again click on middle screen text app is crashing, can you tell me where to modify the library please

  10. It’s awesome Tutorial. I following it and adapt it with Mapview. I use PagerActicity extend MapActivity. I have no idea how can i set value to TextView which retrive value from some method like updatewithnewlocation() in PagerActivity. If you don’t mind you can take a look here http://stackoverflow.com/questions/9106740/how-to-update-textview-in-pageradapter-after-using-inflater-inside-instantiatei

    Following you said:
    “instantiateItem()
    This creates the view for a given position. For a real application we would use a Fragment here, or inflate a layout, but to keep the example simple we create a TextView, set the text to the correct value from our titles array, and add it to the ViewPager.”

    In my case , I would use Fragment isn’it? but i don’t know how? if not Do you have any suggestion? Thank you so much

    1. At stackoverflow question, you might see i answer my own question though, i think it’s not good solution. Because another problem occur. I’ve debug it and found that after the following line of code in PagerActivity,

      pager.setAdapter( adapter );
      indicator.setViewPager( pager );

      it won’t call instantiateItem() yet, so i guess view is Null, it will call instantiateItem() when the process finish onCreate() method. That why my problem occur, even i use getInstance(). I can’t set value in onCreate(). The only thing it works at first, because updateWithNewLocation() method. The view be set already on the second call to updateWithNewLocation().

      Question: In case, I would like to set value since the process in onCreate, How do i do?

      Sorry, I’m not good at English, hope u understand
      Thanks

  11. Hi,
    When I add the ViewPagerIndicator library to a working android project, the project force close and does not work anymore. And when I remove the library the project works again.
    Any idea how to solve it?
    Thanks.

  12. Hey,

    Thanks for the tutorial but I’m having issues after I create a new project from the /library/ folder of the plugin. After I create the new project I add the comparability libraries as well as fix the project properties. Yet, I’m still receiving errors.

    For example, in CirclePageIndicator.java I’m receiving this error on line 311:

    The method isFakeDragging() is undefined for the type ViewPager

    My guess is it has something to do with android-support-v4.jar. I have r6 and have the most recent git version of ViewPagerIndicator. Not sure what’s going wrong tho…

    Any help would be appreciated. Thanks!

    1. Did you get any hold of the issue?
      I am developing for 4.0 and think I am using v13, is it fine? As v13 has v4

      And how did you solved your problem?

      Please help/

  13. Thank you very much.
    Because of you I got rid of my heavy ViewFlipper and I have a smooth ViewPager that takes big big cursors. cool

  14. Hi ,it is very use full to me,But I have one issue i.e.. I have 2 screens in every screen it contains grid view ,here my intention is i want to drag one grid view item of one screen to another screen.
    Can u help me to solve these problem.

    Advance Thanks

  15. I encounter some problem.
    When I go to the step “Let’s create a new Android 2.3.3 Project named “ViewPager” with a package name of “com.stylingandroid.viewpager”. Next we need to add the compatibility library support as we did before by right clicking the project, then selecting “Android Tools|Add Compatibility Library…”. Now we can add the ViewPagerIndicator library by right clicking the project and selecting “Properties|Android”, then clicking “Add…” in the Library section and selecting the ViewPagerIndicator library. Then click “OK”.”

    The green tick when I select the project. Then when I reopen, it become a red cross .

    The location pointed to the GIT library folder I downloaded earlier. The step “create new project from existing source”, what is this for?

    1. I have resolved,

      you must copy all the file on library in a new folder in eclipse workspace (i have named this viewpageindicator), after that you must create a new android project from an existing source w/ the folder you have created earlier.
      Is not finish because you must enable is library right click on the project/propreties/android/is labriry selected.

      Now you can follow the article from “Now we’re ready to start coding. First we need to edit res/layout/main.xml and add our ViewPager and ViewPagerIndicator:”

      1. It doesn;t allow me to create a new android project from source, it doesn’t import the android manifest file and the build crashes. It sugests me to simply import the project via file|import…

  16. hi its a nice article.
    but i have problem when i try to add arrow on TitlePageIndicator
    can you help me?

    Any help would be appreciated. Thanks!

  17. Hi, this is really a great article as i have been in dire need of this for a while. I have been able to setup the project in my workspace and it compiles in eclipse without errors. However when I run the application it force closes without launching and displays the famous application *** has stopped working…
    Please do you know what could be wrong? I have tried it for both tutorial 1& 2 but am facing the same problem. Thanks

  18. It is possible even for 2.2 version. I had some problems with Git imort , but it is only important to rename package.. from some silly you get by default in ViewPagerIndicator into this from example

    com.jakewharton.android.viewpagerindicator

    and everything works fine THANK YOU

  19. Great Tutoral ,but it would be advisable to correct it!
    1,You have to copy libary folder into your workspace directory…
    2,Package name com.jakewharton.android.viewpagerindicator changed to com.viewpagerindicator….
    Thanks 🙂

    1. Hey Dominik

      Thank you !!! You saved my day with this tip!
      2.Package name com.jakewharton.android.viewpagerindicator changed to com.viewpagerindicator….

      But great tutorial…

  20. “import com.jakewharton.android.viewpagerindicator.TitleProvider” causes an error as there is no TitleProvider anywhere in the source code. Can someone tell me where I can find it?

    1. Ok. I just found out that TitleProvider is no longer needed with the latest version of ViewPagerIndicator. You can override getTitle from the regular PagerAdapter. Thought I may not be the only one that didn’t know that.

  21. Hi, I’m on Eclipse Version: 3.7.2 and I found impossible to install this library in order to use in my project, I’ve tried trough using the GIT method and I can’t get it working. It doesn’t load the AndroidManifest file when I create a new Andreid project from an existing source….

    A more detailed explanation would be really appreciated.

    Thank you!

  22. Hi , Can anyone provide the library and sample code that is used in this tutorial? The link for lib and sample code given here is modified now with new lib and sample code. Help plzzz Thanks

    1. I’m working on an update article to cover the current version as a lot has changed since the original article was published. It’s going to be a few weeks before the new article gets published, though.

      1. OK , thank you for your response. Do you have the library that is used in this article , i really need it urgently : / . To wait for weeks , my client will kill me. : (

        1. I’m not the author of the library, but the latest version can always be found at viewpagerindicator.com. There is also an archive of previous versions at https://github.com/JakeWharton/Android-ViewPagerIndicator/tags. I don’t know the precise version that this example code was built against as the instructions are simply for the latest, bleeding-edge version, but one of the 1.x.x releases should probably wrk with the example code in this article.

  23. Actually latest one is using fragmentation , what i want to show is listeview and mapview , as i am beginner finding it difficult how to plugin these 2 in it.

  24. Very nice but I would like to know how to implement buttons, I mean, I created buttons on xml files but I do not know how to implement in fragments and activity

  25. hi….
    i have a problem in viewPager….i want to know how to remove a page from view pager. i tried to call destroyItem but its not working…

    Please share some example to remove a page from a viewPager

  26. Hai,

    I have downloaded then zip file, and finish imported, but there occurs many errors, is library also have to add? if yes, where to get it?
    Thanks in advance.

    1. Please note that, as mentioned in this article, there is a newer article covering this topic. You’ll need to follow the instructions in that article to get the current version of the library working.