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 version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<com.jakewharton.android.viewpagerindicator.TitlePageIndicator
		android:id="@+id/indicator" 
		android:layout_width="fill_parent"
		android:layout_height="wrap_content" />
	<android.support.v4.view.ViewPager 
		android:id="@+id/viewpager"
		android:layout_width="fill_parent" 
		android:layout_height="wrap_content"
		android:layout_weight="1" />
</LinearLayout>

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:

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 ) {}
}

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:

@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 );
}

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. This article originally appeared on Styling Android.

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License

Send the author to the moon!

Creative Commons License
ViewPager – Part 1 by Styling Android, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Terms and conditions beyond the scope of this license may be available at blog.stylingandroid.com.

Tags: ,

78 Responses to “ViewPager – Part 1”

  1. Peter says:

    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 ?

  2. Barkside says:

    Works like a dream! Thanks! I will now try to inflate different layouts instead of the textview…

  3. Larry says:

    Could you post an example with listviews instead of textviews? I am really confused on how to use listviews.

  4. Christopher says:

    Great

    article, thank you.

  5. Kev says:

    Great tutorial, thanks!

  6. Raju says:

    Thanks a lot for the complete example with clear explanation

  7. Donghyuk says:

    Really thanks alot! It makes my app very beautiful!

  8. Dimitri says:

    Very helpful!!Keep on great work!

  9. Neilers says:

    You might want to check this out:

    https://github.com/JakeWharton/Android-ViewPagerIndicator

    It’s the swipey tabs, but implemented exactly like the ones in the new market (swipey tabs are swipable too) AND in the new google music app.

    • Mark Allison says:

      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.

      • Neilers says:

        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.

  10. Chris Murone says:

    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?

  11. xav says:

    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

    • Mark Allison says:

      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.

      • xav says:

        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 ?

  12. Luke says:

    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

  13. Travel Blogs says:

    Thank you, thank you, thank you! Couldn’t figure out how to incorporate the project from the github page (https://github.com/JakeWharton/Android-ViewPagerIndicator) into Eclipse … clear step by step guides for developers of all levels are a rare thing on the web

  14. frontine says:

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

  15. lucas says:

    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

  16. Massimo says:

    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?

    • Mark Allison says:

      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.

      • Massimo says:

        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.

  17. Jun says:

    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.

  18. Siva says:

    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

  19. April says:

    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

    • April says:

      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

  20. Corentin says:

    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.

  21. Radegast says:

    Package name com.jakewharton.android.viewpagerindicator changed to com.viewpagerindicator . Check it in your example.

  22. Ken says:

    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!

    • sourabh says:

      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/

  23. Yann says:

    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

  24. Phanikanth says:

    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

  25. neobie says:

    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?

    • Andrea says:

      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:”

      • Andrei says:

        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…

  26. romanzah says:

    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!

  27. Pelumi says:

    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

  28. PARMENID says:

    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

  29. Dominik says:

    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 :-)

    • bruno says:

      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…

  30. Nick says:

    “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?

    • Nick says:

      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.

  31. Andrei says:

    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!

  32. Ahmed says:

    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

    • Mark Allison says:

      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.

      • Ahmed says:

        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. : (

        • Mark Allison says:

          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.

  33. Ahmed says:

    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.

  34. Renato Ambrosio says:

    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

  35. Arati says:

    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

  36. [...] adding library I am a noob to android and i am trying to add a library for viewpagerindicaor as this tutorial instructs me to do. However, when i add the library i get a an error [...]

  37. Vishnu says:

    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.

    • Mark Allison says:

      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.

  38. lo says:

    koooooooooooo

  39. sohi says:

    import com.jakewharton.android.viewpagerindicator.TitleProvider; is not available when I am importing this.

Leave a Reply