Whether you have just started out in Android app development or are a veteran of the craft, it probably won’t be too long before you’ll need to implement horizontally scrolling sets of views. Many existing Android apps already use this UI pattern, such as the new Android Market, Google Docs and Google+. ViewPager standardizes the implementation.
ViewPager was released as part of the Compatibility Package revision 3 and works with Android 1.6 upwards. After following the instructions to obtain the package you can right-click on your Android project in Eclipse, choose ‘Android Tools’ and ‘Add Compatibility Library’, making the new classes available.
ViewPager is a ViewGroup and works in a similar manner to AdapterViews (like ListView and Gallery) so it shouldn’t feel too foreign. Note that if you use ViewPager in an xml layout, be sure to use the full class reference, e.g.

ViewPagers source their views from PagerAdapters which give you have full control over the reuse and recycling of the views. A PagerAdapter implementation called FragmentPagerAdapter is provided to facilitate the use of Fragments in a ViewPager; This is immensely powerful and as simple as implementing getCount() and getItem(). There is a sample called Fragment Pager Support provided in the Support Demos to illustrate this.
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
}
FragmentPagerAdapter will detach each fragment as you swipe through the list, but keep them in memory so they can simply be reattached when the user swipes back. If you have a larger number of Fragments, the FragmentStatePagerAdapter is worth considering as it will remove them, with the downside being they need to be rebuilt as the user swipes back to them. So, if you have fewer, more complex fragments the FragmentPagerAdapter makes sense, but consider FragmentStatePagerAdapter for larger sets.
On the more simplistic side I recently wrote a ViewPager/PagerAdapter example that serves up simple TextViews. One thing to note is that if you are implementing your own PagerAdapter it is up to you, the developer, to add and remove your views to and from the ViewGroup. To facilitate this the ViewPager is passed into the PagerAdapter methods instantiateItem() and destroyItem().
@Override
public Object instantiateItem(View collection, int position) {
View v = layoutInflater.inflate(…);
…
((ViewPager) collection).addView(v,0);
return tv;
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((TextView) view);
}
The source code for ViewPager is also included and available in /extras/android/compatibility/v4/src. It is worth checking as you can generate the reference documentation from it using Javadoc. In the reference docs / source you’ll find other useful methods, for example setOnPageChangeListener(), which enables your application to track which View is currently visible.
If you are launching an app onto Android Market that uses ViewPager then please ping me on Google+ or Twitter, I’d love to see how widely it is being used and the innovative scenarios in which it appears.
This tutorial shows how to replace the default Spinner graphics in a Google Android application.
This is an example of the default Spinner graphics from the default “Dark” theme in the current version of the Android SDK:
It’s nice and big for eventual use with touchscreen hardware, but it kind of looks like the bright orange Hot Wheels car tracks I used to make ramps with as a child. Especially if your UI isn’t orange and gray.
Substituting custom graphics for Spinners follows the same basic method shown in Custom Buttons, but it is a touch more complicated, so you might want to refer to that tutorial first.
The Android Spinner is made up of two parts. The first is the larger background image (the part that looks like a Hot Wheels car track) and the other is the selector image, which is the small graphic on the right side with the little arrows in it. The selector image changes depending on whether the Spinner dropdown is showing, and which element in the Spinner list is showing.
To view it’s contents, just change .jar to .zip, and extract it with your favorite Unzip application. These are the default Dark theme images, stored as compiled Nine-Patch PNG files: :
spinner_normal.9.png
spinner_press.9.png
spinner_select.9.png
In creating your new Spinner background graphics, I’d suggest starting with these as a model. Copy them to a working folder, and edit them in your favorite image editor.
You can use the Android.jar image files as a starting point, but it’s important to realize that these Nine-Patch images have already been compiled into the .jar file, so the borders that specify the stretchable and drawable sections of the image have already been stripped from the file. You’ll need to add a 1-pixel wide border around the entire image, and define your own stretchable and drawable sections. This is easy enough to do, so I won’t describe it any further here.
Once you’ve created your new button graphics, just import them into your drawable folder in Eclipse.
You’ll then want to create a new XML file in the drawable folder to associate these images with your new Spinner. I’ve named my XML file myspinner_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:state_pressed="false"
android:drawable="@drawable/myspinner_select" />
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="@drawable/myspinner_press" />
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="@drawable/myspinner_press" />
<item android:drawable="@drawable/myspinner_normal" />
</selector>
The <selector> tag allows you to provide multiple states for the Spinner, just as you did for your Button in Custom Buttons(i.e. normal, focused and pressed). Note the android:state_focused andandroid:state_pressed properties. The drawables that are associated with those states are the 9.PNG files you imported above, without the “.9.png”.
Now to associate this Spinner drawable in your XML layout file, all you have to do is assign it to the android:background property:
<Spinner android:id="@+id/spinner_chemical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:background="@drawable/myspinner_background"/>
Now, depending on what you made your new background graphics look like, you should have a spinner that looks something like this:
The selector has a number of states, each with its own image. They’re stored in the same place as the Spinner background graphics, and these are the names:
btn_dropdown_down.9.png
btn_dropdown_left_only.9.png
btn_dropdown_left_right_collapsed.9.png
btn_dropdown_neither.9.png
btn_dropdown_neither_up_down.9.png
btn_dropdown_right_only.9.png
btn_dropdown_up.9.png
btn_dropdown_up_down.9.png
To replace them, I’d suggest starting with these graphics, and making your own. Much like the background graphics, they’re Nine-Patch PNG files. The ones in the Jar are precompiled, so you’ll need to add the border yourself. If you don’t, these graphics will get stretched across the entire Spinner, rather than sitting on the right side, which is what you want them to do.
Figuring out how to set the Nine-Patch border for these files is a little tricky, so here’s how you’ll want to set it up to get it to draw on the right side of the Spinner:
![]()
And here’s a larger example. so you can see the border better:
This border could easily be modified to display the selector on the left side of the Spinnner, or anywhere else that you please.
Once you have your new Selector graphics imported into your application’s drawable folder, you need to set up an XML file for it, also in drawable. I’ve named mine myspinner_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- DROPDOWN SHOWING-->
<item android:state_first="true"
android:state_dropdown_showing="true"
android:drawable="@drawable/btn_dropdown_down"
/>
<item android:state_middle="true"
android:state_dropdown_showing="true"
android:drawable="@drawable/btn_dropdown_up_down"
/>
<item android:state_last="true"
android:state_dropdown_showing="true"
android:drawable="@drawable/btn_dropdown_up"
/>
<item android:state_single="true"
android:state_dropdown_showing="true"
android:drawable="@drawable/btn_dropdown_neither_up_down"
/>
<!-- DROPDOWN NOT SHOWING-->
<item android:state_first="true"
android:state_dropdown_showing="false"
android:drawable="@drawable/btn_dropdown_right_only"
/>
<item android:state_middle="true"
android:state_dropdown_showing="false"
android:drawable="@drawable/btn_dropdown_left_right_collapsed"
/>
<item android:state_last="true"
android:state_dropdown_showing="false"
android:drawable="@drawable/btn_dropdown_left_only"
/>
<item android:state_single="true"
android:state_dropdown_showing="false"
android:drawable="@drawable/btn_dropdown_neither"
/>
</selector>
As you can see, the Spinner selector has a number of states. It responds to these states:
Each sensible combination of these states needs an image associated with it. There are 8 such combinations, shown above.
Now back to your layout XML file. You’ll need to add this Selector drawable to your spinner. This is done with the android:spinnerSelector property:
<Spinner android:id="@+id/spinner_chemical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawSelectorOnTop="true" android:spinnerSelector="@drawable/myspinner_selector" android:background="@drawable/myspinner_background"/>
If you’ve done everything correctly, you should now have a completely custom Spinner. Here’s mine:
