The ViewFlipper is a really useful view on android. It allows you to build up a set of pages and easily move between them. At its simplest, you call the showPrevious and showNext methods on the view and it moves through your pages and wraps back to the beginning when it gets to the end. At the other end of the spectrum you can incorporate gestures to enable the user to swipe through the pages, and with the ViewFlipper handling just three views you can allow the user to move through any number of pages.
In this first article, I am just going to show you a simple application so that you can see what it does. I will go into the more complex examples in other posts.
So, this application is going to show two buttons at the top to allow the user to go to the next and previous pages. Beneath them will be the ViewFlipper which contains three TextViews.
So firstly create a new android project called ViewFlipperSimple and change the res/layout/main.xml file to be the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?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"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:id="@+id/previous" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Prev" /> <Button android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Next" /> </LinearLayout> <ViewFlipper android:id="@+id/flipper" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:text="view 1" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <TextView android:text="view 2" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <TextView android:text="view 3" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </ViewFlipper> </LinearLayout> |
Now replace the contents of ViewFlipperSimple.java with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.example.android.viewflippersimple; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ViewFlipper; public class ViewFlipperSimple extends Activity implements OnClickListener { Button next; Button previous; ViewFlipper flipper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); flipper = (ViewFlipper)findViewById(R.id.flipper); next = (Button) findViewById(R.id.next); previous = (Button) findViewById(R.id.previous); next.setOnClickListener(this); previous.setOnClickListener(this); } @Override public void onClick(View v) { if (v == next) { flipper.showNext(); } else if (v == previous) { flipper.showPrevious(); } } } |
You can see on line 10 that the Activity class implements the OnClickListener class. This is so that our activity knows when the user clicks on the buttons: lines 24 and 25 tell the buttons that we want to know about the clicks.
The onClick method determines which button was pressed and calls showNext or showPrevious on the ViewFlipper.
That is all we need to do for the application to work, so try running it and see what happens.
Unfortunately, that is not the whole story, because on android 2.1 there is a problem with changing orientation. I also get the crash on android 2.2. An IllegalArgumentException occurs in the onDetachedFromWindow method of ViewFlipper. You can find out about the about the problem here. In the emulator, with the num lock key off press the 7 key to change to landscape and then the 9 key to go to back to portrait. Did the app crash? If not try going back and forth between landscape and portrait quickly. After the crash you should see something like this in the Debug window:
Thread [<1> main] (Suspended (exception IllegalArgumentException)) WindowManagerImpl.removeViewImmediate(View) line: 226 Window$LocalWindowManager.removeViewImmediate(View) line: 436 ActivityThread.handleDestroyActivity(IBinder, boolean, int, boolean) line: 3684 ActivityThread.handleRelaunchActivity(ActivityThread$ActivityRecord, int) line: 3789 ...
The java exception is something like:
java.lang.IllegalArgumentException: Receiver not registered: android.widget.ViewFlipper$1@44b6ab90 at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:667) at android.app.ApplicationContext.unregisterReceiver(ApplicationContext.java:747) at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:321) at android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)
There is a workaround for this bug. Which is to create a wrapper class around ViewFlipper and catch the exception. To fix our application create a new class called MyViewFlipper and change the code to be:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import android.content.Context; import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.widget.ViewFlipper; public class MyViewFlipper extends ViewFlipper { public MyViewFlipper(Context context) { super(context); } public MyViewFlipper(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDetachedFromWindow() { if (Integer.parseInt(Build.VERSION.SDK) >= 7) { try { super.onDetachedFromWindow(); } catch (IllegalArgumentException e) { Log.e("MyViewFlipper", "Android issue 6191: http://code.google.com/p/android/issues/detail?id=6191"); } finally { super.stopFlipping(); } } else { super.onDetachedFromWindow(); } } } |
All we need to do to use our extended ViewFlipper is to modify the AndroidManifest.xml file. Change “ViewFlipper” to be “com.example.android.viewflippersimple.MyViewFlipper” on lines 21 and 37.
Run the application again and try changing the orientation. The application should function as you would expect. If you look in the LogCat window in eclipse you will see the red exception line that the MyViewFlipper class puts out when it absorbs the exception.
Download
You can download this example from here.
To add this example to eclipse go to File|New|Android Project, select “Create project from existing source” and then browse to the folder inside of the downloaded zip file.
no comment until now