With Halloween just behind us, I now have a bucket of candy sitting front and center on my kitchen counter. It calls my name when no one else is around to hear. Then I have to play dumb when my son asks what happened to the purple Laffy Taffy he’d been saving. The one with the terrible joke on the inside of the wrapper, about a dog limping into a saloon and announcing: “I’m looking for the man who shot my paw!” I guess if my son happens to read my post this week, I’ll be busted. But I decided to include that particular Laffy Taffy gem in this tutorial demonstrating Android‘s ViewFlipper widget.

What’s a ViewFlipper?

The ViewFlipper is a nifty widget that can be used to slide views in and out of the user’s current view port. At times I find it a handy UI replacement for the tab widget (which I’ve stated before I’m not overly fond of). What I like most about the ViewFlipper is the slick user experience. It’s the same sort of effect that is prevalent on Windows Phone 7, and was used by Google to jazz up the latest incarnation of the Android Market.

Despite the widget only recently gaining popularity on Android, it’s been around since version 1.0 of the API. (Read the official ViewFlipper documentation.) However, I don’t think the developer documentation makes it immediately obvious how to use the widget in your applications. In particular, puzzling through the sliding in and out animation transitions can be a little tough. Maybe not as tough as ignoring the candy bowl sitting on my kitchen counter, assuring me no one will notice if I take just one more Laffy Taffy, but still, it requires you to put on your thinking cap. If you’d like to download and import the entire project detailed in this tutorial, you can do so here. Otherwise, let’s begin with a new project in Eclipse.

ViewFlipper widget tutorial

1. Create a new Android project. Target any API greater than 1.6.

2. In your /res folder, you’ll need a main.xml layout. Notice how the ViewFlipper control contains two linear layouts; these layouts are what the widget will iterate through when you call the next() and previous() methods in your code. Our layouts are simple and just contain a single text view, but you can use any sort of layouts you need in your application.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="View Flipper Demo" />
<ViewFlipper
android:layout_margin="6dip"
android:id="@+id/view_flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<TextView
android:layout_height="wrap_content"
 android:layout_width="wrap_content"
android:textStyle="bold"
android:textColor="#00ff00"
android:textSize="14sp"
android:text="A dog limps into a saloon and says...">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textStyle="bold"
android:textColor="#00ff00"
android:textSize="14sp"
android:text="I'm looking for the man who shot my paw!">
</TextView>
</LinearLayout>
</ViewFlipper>
</LinearLayout>

3. Now comes the tricky part. Create a folder called /anim in your /res directory. In the folder, you’ll want to create four XML files to represent the four transitions we’ll require. Spend a few minutes looking at the x delta values, so you’re sure you understand the effect we are hoping to accomplish.

out_to_left.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="1400"/>
</set>
out_to_right.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="1400"/>
</set>
in_from_left.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="1400" />
</set>
in_from_right.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="1400" />
</set>

4. Now let’s move to our /src folder and add the Main.java file. We’ll create a couple of private variables, and use the on create method to attach our ViewFlipper widget.

Main.java
package com.authorwjf;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.ViewFlipper;
public class Main extends Activity {
private ViewFlipper vf;
private float lastX;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
vf = (ViewFlipper) findViewById(R.id.view_flipper);
}
}

5. The final step is to add a touch handler to our Main.java activity. The on touch handler will use a simple technique of comparing our last x position with the current one to determine if the user is swiping left to right or right to left. We use this information when deciding which animations to assign to the ViewFlipper and whether to invoke the next() or previous() method on the control.

Main.java
@Override
public boolean onTouchEvent(MotionEvent touchevent) {
switch (touchevent.getAction())
{
case MotionEvent.ACTION_DOWN:
{
lastX = touchevent.getX();
break;
}
case MotionEvent.ACTION_UP:
{
float currentX = touchevent.getX();
if (lastX < currentX)
{
if (vf.getDisplayedChild()==0) break;
vf.setInAnimation(this, R.anim.in_from_left);
vf.setOutAnimation(this, R.anim.out_to_right);
vf.showNext();
}
if (lastX > currentX)
{
if (vf.getDisplayedChild()==1) break;
vf.setInAnimation(this, R.anim.in_from_right);
vf.setOutAnimation(this, R.anim.out_to_left);
vf.showPrevious();
}
break;
}
}
return false;
}

There you have it — a pretty snazzy way to present a pretty lame joke. You can play with the duration property in the /anim folder to speed up or slow down the transition. A still picture doesn’t do it justice, so if you get a minute load the APK onto your phone or one of the emulators and have a look.

Until next time, enjoy the leftover Halloween candy. I know I will.

Figure A

Figure B