tags:

views:

783

answers:

4

Can i create the same kind of navigation that I have on the main screens? That is, I want different screens that I can navigate between using the touch-and-drag? I haven't seen anything about it, so it was time to ask :)

Oh, Im talking about apps for android :)

A: 

There are no widgets built into Android to do this. You can look at the source code of the existing home screen to see how it does it, or use ViewFlipper and the new gesture system to attempt to emulate it.

CommonsWare
+5  A: 

There is nothing built-in, but you can use ViewFlipper, GestureDetector and Animation to "fake it" (you wont get the tactile drag of the home screen using this method):

public class SwipeExample extends Activity {

    private static final int LEFT = 0;
    private static final int RIGHT = 1;

    ViewFlipper flipper;
    GestureDetector gestureDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     flipper = (ViewFlipper) findViewById(R.id.flipper);
     gestureDetector = new GestureDetector(new MyGestureDetector());

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
     if (gestureDetector.onTouchEvent(event))
      return true;
     else
      return false;
    }

    private Animation animateInFrom(int fromDirection) {

     Animation inFrom = null;

     switch (fromDirection) {
     case LEFT:
      inFrom = new TranslateAnimation(
        Animation.RELATIVE_TO_PARENT, -1.0f, 
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f);
      break;
     case RIGHT:
      inFrom = new TranslateAnimation(
        Animation.RELATIVE_TO_PARENT, +1.0f, 
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f);
      break;
     }

     inFrom.setDuration(250);
     inFrom.setInterpolator(new AccelerateInterpolator());
     return inFrom;
    }

    private Animation animateOutTo(int toDirection) {

     Animation outTo = null;

     switch (toDirection) {
     case LEFT:
      outTo = new TranslateAnimation(
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, -1.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f);
      break;
     case RIGHT:
      outTo = new TranslateAnimation(
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, +1.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f,
        Animation.RELATIVE_TO_PARENT, 0.0f);
      break;
     }

     outTo.setDuration(250);
     outTo.setInterpolator(new AccelerateInterpolator());
     return outTo;
    }

    class MyGestureDetector extends SimpleOnGestureListener {

     // from:
     // http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/

     private static final int SWIPE_MIN_DISTANCE = 120;
     private static final int SWIPE_MAX_OFF_PATH = 250;
     private static final int SWIPE_THRESHOLD_VELOCITY = 200;

     @Override
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
      try {
       if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
        return false;
       if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
         && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
        // right to left swipe
        flipper.setInAnimation(animateInFrom(RIGHT));
        flipper.setOutAnimation(animateOutTo(LEFT));
        flipper.showNext();
       } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
         && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
        // left to right swipe
        flipper.setInAnimation(animateInFrom(LEFT));
        flipper.setOutAnimation(animateOutTo(RIGHT));
        flipper.showPrevious();
       }
      } catch (Exception e) {}
      return false;
     }
    }

}
Jeff Gilfelt
A: 

Thanks for that, I will take a look at it =)

Ted
A: 

there is a problem with that solution in a listview and I am not quite sure how to fix it - as long as the list is scrolled the abs calculation is off by a row

Unique