In this tutorial we’ll discuss and implement Android ViewFlipper. ViewFlipper in android is mainly used in cases when we need to transform one view into another.
Android ViewFlipper
ViewFlipper in android is an extension of ViewAnimator class, which animates between two or more views that have been added to it. Only one child is shown at a time and the user can flip to view the other child views. We can also implement the ViewFlipper such that it automatically flips between the views at regular intervals. A ViewFlipper can be used in gallery apps to navigate between the images.
Android ViewFlipper supports the methods : setInAnimation() and setOutAnimation() in which we can use either the default animation from the android system or the write our own animation class. To control the auto-flip option, we can start and stop the timer on the ViewFlipper by invoking startFlipping() and stopFlipping() methods. We can set the auto flip interval using setFlipInterval(period). The next and previous child views are invoked using showNext() and showPrevious() methods on the ViewFlipper object.
In this tutorial we’ll create an application that consists of 3 screens. We’ll show automatic flipping on each of them and use Android MotionEvent class to swipe left and right to flip between the first two screens.
Android ViewFlipper Example Project Structure
This project consists of four custom animation classes that will show transitions between the ViewFlipper views.
Android ViewFlipper Example Code
The content_main.xml
file is defined as shown below.
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.journaldev.viewflipper.MainActivity" tools:showIn="@layout/activity_main"> <ViewFlipper android:id="@+id/view_flipper" android:layout_width="fill_parent" android:layout_height="fill_parent"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:adjustViewBounds="true" android:background="@android:color/black" android:scaleType="centerCrop" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="First Child" android:textColor="@android:color/white" android:textSize="18dp" android:textStyle="bold" /> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:adjustViewBounds="true" android:background="@android:color/darker_gray" android:scaleType="centerCrop" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="Second Child" android:textSize="18dp" android:textStyle="bold" /> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:adjustViewBounds="true" android:background="@android:color/holo_green_light" android:scaleType="centerCrop" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="Third Child" android:textSize="18dp" android:textStyle="bold" /> </RelativeLayout> </ViewFlipper> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentTop="true" android:gravity="center" android:orientation="horizontal"> <Button android:id="@+id/play" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="10dp" android:background="@android:drawable/ic_media_play" /> <Button android:id="@+id/stop" android:layout_width="50dp" android:layout_height="50dp" android:background="@android:drawable/ic_media_pause" /> </LinearLayout> </RelativeLayout> |
The ViewFlipper
tag consists of three sibling RelativeLayout child views. Only one will be displayed at a time.
The four animation classes are placed in res/anim folder and are defined as below :
in_from_left.xml
1 2 3 4 5 6 7 8 9 |
<set xmlns:android="https://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
1 2 3 4 5 6 7 8 9 |
<set xmlns:android="https://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> |
out_from_left.xml
1 2 3 4 5 6 7 8 |
<set xmlns:android="https://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_from_right.xml
1 2 3 4 5 6 7 8 |
<set xmlns:android="https://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> |
The MainActivity.java
is defined as below.
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
public class MainActivity extends AppCompatActivity { private ViewFlipper mViewFlipper; private Context mContext; private float initialX; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mContext = this; mViewFlipper = (ViewFlipper) this.findViewById(R.id.view_flipper); findViewById(R.id.play).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mViewFlipper.setAutoStart(true); mViewFlipper.setFlipInterval(1000); mViewFlipper.startFlipping(); Snackbar.make(view, "Automatic view flipping has started", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); findViewById(R.id.stop).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mViewFlipper.stopFlipping(); Snackbar.make(view, "Automatic view flipping has stopped", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); } @Override public boolean onTouchEvent(MotionEvent touchevent) { switch (touchevent.getAction()) { case MotionEvent.ACTION_DOWN: initialX = touchevent.getX(); break; case MotionEvent.ACTION_UP: float finalX = touchevent.getX(); if (initialX > finalX) { if (mViewFlipper.getDisplayedChild() == 1) break; mViewFlipper.setInAnimation(AnimationUtils.loadAnimation(mContext, R.anim.in_from_left)); mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mContext, R.anim.out_from_left)); mViewFlipper.showNext(); } else { if (mViewFlipper.getDisplayedChild() == 0) break; mViewFlipper.setInAnimation(AnimationUtils.loadAnimation(mContext, R.anim.in_from_right)); mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mContext, R.anim.out_from_right)); mViewFlipper.showPrevious(); } break; } return false; } } |
The onTouchEvent
method is implemented to detect swipes.
MotionEvent.ACTION_DOWN is the action when the touch gesture has first started and it notes the location.
MotionEvent.ACTION_UP marks the touch gesture as finished and also gives the intermediate points since the last action.
If we’re on the first child and a gesture from left to right is made the ViewFlipper would animate and display the second child. Vice-versa for the opposite gesture.
Pressing the play button, animates and flips between the child views automatically at regular intervals.
The application output in action is shown below.
This brings an end to Android ViewFlipper tutorial. You can download the final Android ViewFlipper Project from the link below.