In September 2011 I began a series on Styling Android about ViewPager and Jake Wharton’s ViewPagerIndicator library. This proved to be a very popular series, but the comments on those articles show that there has been some changes in Jake’s library which means that the code in the original articles no longer works with the latest version of the library. In this series we’ll revisit ViewPager and ViewPagerIndicator, get the old example code working with the latest version of the library, and also look at some alternatives.
The methods for obtaining the ViewPagerIndicator library have not changed since the original article on ViewPager, so I won’t bother repeating them here.
Once we have checked out the latest version (2.4.1 at the time of writing) of ViewPagerIndicator/library, we need to configure our existing ViewPager code to use this library by right clicking on it in Package Explorer, then selecting “Properties|Android”. Then in the “Library” panel, remove any existing library settings, and adding the ViewPagerIndicator-library that we’ve just checked out.
The first problem that we’ll see is that there is an error in res/values/styles.xml. This is because the style specifies a parent of Widget.TitlePageIndicator
which was included in the earlier version of the library, but is no longer there. We can see how to resolve this by looking at Jake’s sample application code, and see how the styles are organised there. If we look here we can see that CustomTitlePageIndicator
style no longer inherits from a style defined in the library itself, so all we need to do to fix our code is remove the parent specification. If we compare the style in Jake’s sample to our style we can see that they’re pretty similar, so we’ll just go with the one we have, just without the parent definition.
The second major thing that has changed is the package name of the library. Previously it was com.jakewharton.android.viewpagerindicator
, but now it is com.viewpagerindicator
, so we must change the imports in ViewPagerActivity. We must also update the package name in res/layout/main.xml as this also refers to the incorrect package.
Thirdly, if we look at ViewPagerAdapter we can see that we have to implement the TitleProvider interface. If we change the package name as before, we still see an error because this interface is no longer a part of the library. The reason for this is because this version of ViewPagerIndicator is based upon a newer version of the support library, and this has an expanded API which has a title provider built in. We must remove the TitleProvider import, and implements directive from our ViewPagerAdapter class definition, and change the method name from getTitle
to getPageTitle
.
If we now run this we can see that we have the behaviour that we did previously:
Getting the existing code to work with the current version of the library wasn’t too difficult, but there we a few changes that were worthy of some explanation.
In the next part of this series we’ll look at an alternative to Jake’s ViewPagerIndicator library.
The source code for this article can be found here.
© 2012, Mark Allison. All rights reserved.
Copyright © 2012 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.
Okay, I tried this approach, nothing is working. I built the jake wharton library separately and that seems okay but when I try to build his sample programs no matter what I do, I get the error during the build:
Errors running builder ‘Android Pre Compiler’ on project ‘ListSamples’.
java.lang.NullPointerException
I get this error as soon as I add the jar file that was created by building his library.
I realize you don’t have time to debug everyone’s code, but I just thought I’d mention it.
Thank you
Tried everything suggested, once I got past this error, but then got the error when launching…
01-09 20:43:20.161: E/dalvikvm(2455): Could not find class ‘com.viewpagerindicator.TitlePageIndicator’, referenced from method com.stylingandroid.viewpager.ViewPagerActivity.onCreate
01-09 20:43:20.167: W/dalvikvm(2455): VFY: unable to resolve check-cast 462 (Lcom/viewpagerindicator/TitlePageIndicator;) in Lcom/stylingandroid/viewpager/ViewPagerActivity;
01-09 20:43:20.167: D/dalvikvm(2455): VFY: replacing opcode 0x1f at 0x001c
01-09 20:43:20.248: D/dalvikvm(2455): VFY: dead code 0x001e-0024 in Lcom/stylingandroid/viewpager/ViewPagerActivity;.onCreate (Landroid/os/Bundle;)V
01-09 20:43:20.407: D/AndroidRuntime(2455): Shutting down VM
01-09 20:43:20.417: W/dalvikvm(2455): threadid=1: thread exiting with uncaught exception (group=0x40015560)
01-09 20:43:20.500: E/AndroidRuntime(2455): FATAL EXCEPTION: main
01-09 20:43:20.500: E/AndroidRuntime(2455): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.stylingandroid.viewpager/com.stylingandroid.viewpager.ViewPagerActivity}: android.view.InflateException: Binary XML file line #6: Error inflating class com.viewpagerindicator.TitlePageIndicator
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.os.Handler.dispatchMessage(Handler.java:99)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.os.Looper.loop(Looper.java:123)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.ActivityThread.main(ActivityThread.java:3683)
01-09 20:43:20.500: E/AndroidRuntime(2455): at java.lang.reflect.Method.invokeNative(Native Method)
01-09 20:43:20.500: E/AndroidRuntime(2455): at java.lang.reflect.Method.invoke(Method.java:507)
01-09 20:43:20.500: E/AndroidRuntime(2455): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-09 20:43:20.500: E/AndroidRuntime(2455): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-09 20:43:20.500: E/AndroidRuntime(2455): at dalvik.system.NativeStart.main(Native Method)
01-09 20:43:20.500: E/AndroidRuntime(2455): Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class com.viewpagerindicator.TitlePageIndicator
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:581)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
01-09 20:43:20.500: E/AndroidRuntime(2455): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.Activity.setContentView(Activity.java:1657)
01-09 20:43:20.500: E/AndroidRuntime(2455): at com.stylingandroid.viewpager.ViewPagerActivity.onCreate(ViewPagerActivity.java:15)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-09 20:43:20.500: E/AndroidRuntime(2455): … 11 more
01-09 20:43:20.500: E/AndroidRuntime(2455): Caused by: java.lang.ClassNotFoundException: com.viewpagerindicator.TitlePageIndicator in loader dalvik.system.PathClassLoader[/data/app/com.stylingandroid.viewpager-1.apk]
01-09 20:43:20.500: E/AndroidRuntime(2455): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
01-09 20:43:20.500: E/AndroidRuntime(2455): at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
01-09 20:43:20.500: E/AndroidRuntime(2455): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.createView(LayoutInflater.java:471)
01-09 20:43:20.500: E/AndroidRuntime(2455): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570)
01-09 20:43:20.500: E/AndroidRuntime(2455): … 20 more
It sounds like you’re not exporting the ViewPagerIndicator library in your project, so it’s not being included in your APK.
Hi. Did you also implemented the vertical viewpager with the latest compatibility library ? thanks a lot!!!