In this post I will show you how to use the touch screen so that you can drag your finger across the screen, and it will switch the screen for you – “iPhone style”!
For this I will be implemented OnTouchListener and overrided the method OnTouch().
To start off, we need to create an Activity with two screens. The two screens will be implemented using a ViewFlipper in the main.xml layout file. Follow the steps in this blog post to set yourself up: Android: Switching screens in an Activity with animations (using ViewFlipper).
1. Now that you have yourself set up, open the Activity1 class.
2. Make the class implement OnTouchListener. The top of the class will look like this:
... import android.view.View.OnTouchListener; public class Activity1 extends Activity implements OnTouchListener{ ...
2. You will have to override the OnTouch() method as well. If you were using eclipse, it might have created the method stub for you:
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
return false;
}
Here is the method that you need to use instead:
public boolean onTouch(View arg0, MotionEvent arg1) { // Get the action that was done on this touch event switch (arg1.getAction()) { case MotionEvent.ACTION_DOWN: { // store the X value when the user's finger was pressed down downXValue = arg1.getX(); break; } case MotionEvent.ACTION_UP: { // Get the X value when the user released his/her finger float currentX = arg1.getX(); // going backwards: pushing stuff to the right if (downXValue < currentX) { // Get a reference to the ViewFlipper ViewFlipper vf = (ViewFlipper) findViewById(R.id.details); // Set the animation vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out)); // Flip! vf.showPrevious(); } // going forwards: pushing stuff to the left if (downXValue > currentX) { // Get a reference to the ViewFlipper ViewFlipper vf = (ViewFlipper) findViewById(R.id.details); // Set the animation vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); // Flip! vf.showNext(); } break; } } // if you return false, these actions will not be recorded return true; }
What I’ve done is added a CASE statement. On press down of the finger we save the current X value. On press up of the finger, after the dragging motion has finished, I check the X value again. I compare the two X values and I make a logical decision whether I should switch the screens forwards or backwards.
3. For the above to work, you need to add a global variable called downXValue that will store the X value when the finger was pressed down. Add the line below at the top of the class:
... public class Activity1 extends Activity implements OnTouchListener{ private float downXValue; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { ...
4. Now, you we will edit the main.xml layout. This is different from the main.xml from the previous post in two ways:
- The two buttons that switched the views have been removed, because we don’t need them anymore and
- I added an ID to the main LinearLayout so that I may reference it in my code.
Here is the entire main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:id="@+id/layout_main" > <ViewFlipper android:id="@+id/details" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <TextView android:id="@+id/tv_country" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#000000" android:textStyle="bold" android:textSize="18px" android:text="Country" > </TextView> <Spinner android:text="" android:id="@+id/spinner_country" android:layout_width="200px" android:layout_height="55px"> </Spinner> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <TextView android:id="@+id/tv_income" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#000000" android:textStyle="bold" android:textSize="18px" android:text="Income" > </TextView> <EditText android:text="" android:id="@+id/et_income" android:layout_width="200px" android:layout_height="55px"> </EditText> </LinearLayout> </ViewFlipper> </LinearLayout>
5. We will have to add a listener for the OnTouch() event in the OnCreate() method of the Activity1 class will be. Add the following two lines:
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set main.XML as the layout for this Activity
setContentView(R.layout.main);
// Add these two lines
LinearLayout layMain = (LinearLayout) findViewById(R.id.layout_main);
layMain.setOnTouchListener((OnTouchListener) this);
...
6. You should also remove the two Button OnClick() events and listeners, because those buttons do not exist anymore. Here is the final version of the Activity1.java class:
package com.warriorpoint.taxman3; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.animation.AnimationUtils; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.ViewFlipper; public class Activity1 extends Activity implements OnTouchListener{ float downXValue; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set main.XML as the layout for this Activity setContentView(R.layout.main); // Add these two lines LinearLayout layMain = (LinearLayout) findViewById(R.id.layout_main); layMain.setOnTouchListener((OnTouchListener) this); // Add a few countries to the spinner Spinner spinnerCountries = (Spinner) findViewById(R.id.spinner_country); ArrayAdapter countryArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, new String[] { "Canada", "USA" }); spinnerCountries.setAdapter(countryArrayAdapter); } public boolean onTouch(View arg0, MotionEvent arg1) { // Get the action that was done on this touch event switch (arg1.getAction()) { case MotionEvent.ACTION_DOWN: { // store the X value when the user's finger was pressed down downXValue = arg1.getX(); break; } case MotionEvent.ACTION_UP: { // Get the X value when the user released his/her finger float currentX = arg1.getX(); // going backwards: pushing stuff to the right if (downXValue < currentX) { // Get a reference to the ViewFlipper ViewFlipper vf = (ViewFlipper) findViewById(R.id.details); // Set the animation vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out)); // Flip! vf.showPrevious(); } // going forwards: pushing stuff to the left if (downXValue > currentX) { // Get a reference to the ViewFlipper ViewFlipper vf = (ViewFlipper) findViewById(R.id.details); // Set the animation vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); // Flip! vf.showNext(); } break; } } // if you return false, these actions will not be recorded return true; } }
That’s it! Run it!
You will see that the button is gone and dragging across to the left or right will switch the screens!
Disclaimer: The back animation is not perfect, I still have to figure out why. It flickers a little. If you figure it out to animate properly please drop me a comment. Thanks!

September 30, 2009 at 11:50
Hi,
Nice post. Very helpful.
I think I’ve the answer to your animation issue. (maybe you’ve already find it)
Instead of using only the 2 animations proposed you have to create 2 more like this :
a push_right_out.xml
and a push_right_in.xml
You have to replace what happens when you click on a button :
Instead of setAnimation(…..);
use
setInAnimation(view.getContext(), R.anim.push_left_in);
setOutAnimation(view.getContext(), R.anim.push_left_out);
for the 1 to 2 view
and
vf.setInAnimation(view.getContext(), R.anim.push_right_in);
vf.setOutAnimation(view.getContext(), R.anim.push_right_out);
for the 2 to 1 view
And you’ll have a very smoothy animation in the two ways.
March 17, 2010 at 14:24
Hi, It is nice starting. But i’m facing problems handling imagebutton controls under multi touch events using the same code. How do we resolve it? When i have three image buttons and kept it as button.setOnTouchListener(this); for three buttons, onTouch() can be able to detect only one button at a time, cann’t be able to detect all the button click when i click on all the buttons at a time as multi touch purpose. How do we resolve it in this case?
April 16, 2010 at 13:33
Awesome tutorial, thanks! I will definitely be using this in my apps.
May 20, 2010 at 07:52
This tutorial is AWESOME!!! I have been struggling building a app and all I had to do is add my elements in the main xml and it works. I also compared the size of my own application that I’m building vs this one, this one is ~145 KB & mine is 2.3 MB.
THANK YOU VERY MUCH!
May 20, 2010 at 07:54
Boyan ROCKS! Please keep adding such good tutorials.
July 2, 2010 at 19:47
Take a look at the alpha settings in each animation xml file. That’s the cause of the flicker.
It animates from 1.0 to 0.0, then quickly sets it back to 1.0