ViewFlipper
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.
Just like ViewFlipper
, ViewSwitcher
is also a ViewAnimator
(they are sub classes of ViewAnimator
) that can hold only two child views and show one at a time.
A 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.
The activity_main.xml layout is defined as shown below:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_blue_light" android:padding="5dp" android:orientation="vertical"> <ViewFlipper android:id="@+id/vfContainer" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.85"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@android:drawable/ic_dialog_email" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:layout_gravity="center_horizontal" android:text="EMail" android:textSize="20dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@android:drawable/ic_dialog_alert" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:layout_gravity="center_horizontal" android:text="Alert" android:textSize="20dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@android:drawable/ic_dialog_dialer" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:layout_gravity="center_horizontal" android:text="Dialer" android:textSize="20dp"/> </LinearLayout> </ViewFlipper> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:orientation="horizontal"> <Button android:id="@+id/btnPlay" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="10dp" android:background="@android:drawable/ic_media_play" /> <Button android:id="@+id/btnStop" android:layout_width="50dp" android:layout_height="50dp" android:background="@android:drawable/ic_media_pause" /> </LinearLayout> </LinearLayout>
The ViewFlipper
tag consists of three sibling LinearLayout
child views. Only one will be displayed at a time.
Also we can add items programmaticaly
int[] resources = { android.R.drawable.ic_dialog_email, android.R.drawable.ic_dialog_alert, android.R.drawable.ic_dialog_dialer }; vfContainer = (ViewFlipper) findViewById(R.id.vfContainer); for (int i = 0; i < resources.length; i++) { ImageView ivIcon = new ImageView(this); ivIcon.setImageResource(resources[i]); vfContainer.addView(ivIcon); }
The four animation classes are placed in res/anim folder and are defined as below.
File 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" /> <alpha android:duration="500" android:fromAlpha="0.1" android:toAlpha="1.0" /> </set>
File 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" /> <alpha android:duration="500" android:fromAlpha="0.1" android:toAlpha="1.0" /> </set>
File out_from_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"/> <alpha android:duration="500" android:fromAlpha="1.0" android:toAlpha="0.1" /> </set>
File out_from_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"/> <alpha android:duration="500" android:fromAlpha="1.0" android:toAlpha="0.1" /> </set>
The MainActivity.java is defined as below:
public class MainActivity extends AppCompatActivity { private ViewFlipper vfContainer; private Context context; private float initialX; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; vfContainer = (ViewFlipper) this.findViewById(R.id.vfContainer); findViewById(R.id.btnPlay).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { vfContainer.setAutoStart(true); vfContainer.setFlipInterval(1000); vfContainer.startFlipping(); Snackbar.make(view, "Automatic view flipping has started", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); findViewById(R.id.btnStop).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { vfContainer.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 (vfContainer.getDisplayedChild() == 1) break; vfContainer.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.in_from_left)); vfContainer.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.out_from_left)); vfContainer.showPrevious(); } else { if (vfContainer.getDisplayedChild() == 0) break; vfContainer.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.in_from_right)); vfContainer.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.out_from_right)); vfContainer.showNext(); } break; } return false; } }
Result
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.