FlingFlipper

Quickly share your Android Code Snippets here...

FlingFlipper

Postby oneaboveall » Mon Nov 01, 2010 4:32 pm

Hello.
I'm pretty new to android, so I might was a bit too hasty to write my own component for such a task.
Anyway, it's a little component that allows you to switch between views with finger flicks, based on a ViewFlipper. Views are switched with simple Translate animation (300ms duration).
Maybe someone will find it useful.

Code: Select all
package eu.es.flicker;

import java.util.ArrayList;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ViewFlipper;

import eu.es.flicker.R;

public class FlingFlipper extends ViewFlipper {

   public FlingFlipper(final Context context) {
      super(context);
      this.init();
   }

   public FlingFlipper(final Context context, final AttributeSet attrs) {
      super(context, attrs);
      this.doAttributes(attrs);
      this.init();
   }
   
   /* ***** ATTRIBUTES ***** */
   
   public final static int BOTH = 0;
   public final static int HORIZONTAL = 1;
   public final static int VERTICAL = 2;
   private int directions;
   
   private void doAttributes(final AttributeSet attrs) {
      final TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.FlingFlipper);
      directions = ta.getInt(R.styleable.FlingFlipper_directions, BOTH);
   }
   
   public int getDirections() {
      return directions;
   }

   public void setDirections(int directions) {
      this.directions = directions;
   }
   
   private FlingFlipper flipper;
   
   /* ***** INIT FingerFlipper ***** */
   private void init() {
      gestures();
      flipper = this;
   }
   
   private final GestureDetector gdt = new GestureDetector(new GestureListener());
   
   private void gestures() {
      setOnTouchListener(new OnTouchListener() {
         @Override
         public boolean onTouch(final View view, final MotionEvent event) {
            gdt.onTouchEvent(event);
            return true;
         }
      });
   }
   
   public void setOnDoubleTapListener(final OnDoubleTapListener onDoubleTapListener) {
      gdt.setOnDoubleTapListener(onDoubleTapListener);
   }
   
   /* ***** GestureListener that listens when user flings in one direction on out FlingFlipper ***** */
   private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    /* FLING DIRECTIONS */
    private static final int R_TO_L = 0;
    private static final int L_TO_R = 1;
    private static final int B_TO_T = 2;
    private static final int T_TO_B = 3;
   private class GestureListener extends SimpleOnGestureListener {
      @Override
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
         if (directions==BOTH || directions==HORIZONTAL) {
               if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                  return flipper.onFling(R_TO_L);
               }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                  return flipper.onFling(L_TO_R);
               }
         }
         if (directions==BOTH || directions==VERTICAL) {
            if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
               return flipper.onFling(B_TO_T);
               }  else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                  return flipper.onFling(T_TO_B);
               }
         }
           return false;
      }
   }
   
   private boolean onFling(final int direction) {
      final ArrayList<TranslateAnimation> deltasHolders = getDeltas().get(direction);
      setOutAnimation(prepareAnimation(deltasHolders.get(0)));
      setInAnimation(prepareAnimation(deltasHolders.get(1)));
      if (direction==R_TO_L || direction==B_TO_T) {
         showNext();
      } else {
         showPrevious();
      }
      if (onFlingPerformedListener != null) {
         onFlingPerformedListener.onFlingPerformed(direction);
      }
      return false;
   }
   
   private TranslateAnimation prepareAnimation(final TranslateAnimation animation) {
      animation.reset();
      animation.setDuration(300);
      return animation;
   }
   
   private ArrayList<ArrayList<TranslateAnimation>> deltas;
   
   @SuppressWarnings("serial")
   private ArrayList<ArrayList<TranslateAnimation>> getDeltas() {
      if (deltas == null) {
         deltas = new ArrayList<ArrayList<TranslateAnimation>>(4) {
            {
               add(new ArrayList<TranslateAnimation>(2){{
                  add(new TranslateAnimation(0, -flipper.getWidth(), 0, 0));
                  add(new TranslateAnimation(flipper.getWidth(), 0, 0, 0));
               }});
               add(new ArrayList<TranslateAnimation>(2){{
                  add(new TranslateAnimation(0, flipper.getWidth(), 0, 0));
                  add(new TranslateAnimation(-flipper.getWidth(), 0, 0, 0));
               }});
               add(new ArrayList<TranslateAnimation>(2){{
                  add(new TranslateAnimation(0, 0, 0, -flipper.getHeight()));
                  add(new TranslateAnimation(0, 0, flipper.getHeight(), 0));
               }});
               add(new ArrayList<TranslateAnimation>(2){{
                  add(new TranslateAnimation(0, 0, 0, flipper.getHeight()));
                  add(new TranslateAnimation(0, 0, -flipper.getHeight(), 0));
               }});
            }
         };
      }
      return deltas;
   }
   
   /* ***** FlingFlipper Listeners ***** */
   
   private OnFlingPerformedListener onFlingPerformedListener;
   
   public interface OnFlingPerformedListener {
      public void onFlingPerformed(final int direction);
   }
   
   public void setOnFlingPerformedListener(final OnFlingPerformedListener onFlingPerformedListener) {
      this.onFlingPerformedListener = onFlingPerformedListener;
   }
   
   @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      super.onSizeChanged(w, h, oldw, oldh);
      deltas = null;
   }
   
}

And in xml:
Code: Select all
<eu.es.flicker.FlingFlipper
         android:id="@+id/quote_ticker_chart_flipper"
         android:layout_width="300px"
         android:layout_height="193px"
      >
               ... Some views you want to be switched on a fling ...
</eu.es.flicker.FlingFlipper>




Some values (and animations) are hardcoded (since I don't need others in my app), though you can easily change them or make customizable.
There is also a possibility to include attributes for enabling only horizontal or vertical flings.

Comment please.
oneaboveall
Freshman
Freshman
 
Posts: 2
Joined: Wed Oct 13, 2010 2:48 pm

Top

Re: FlingFlipper

Postby TheOnoy123 » Tue Jul 12, 2011 9:38 am

where the styleable FlingFlipper ..??
TheOnoy123
Freshman
Freshman
 
Posts: 5
Joined: Fri Jun 24, 2011 12:38 pm

Top

Return to Code Snippets for Android

Who is online

Users browsing this forum: No registered users and 6 guests