Thursday, September 03, 2009

trouble with ViewFlipper

I got totally side-tracked in my Android app trying to do a quick implementation of onFling. The intent was to not have to worry about my GridView filling up with buckets - I thought I could just max out the current view at 9 and implement onFling to take in the swipe gesture from the user to move over and look at the next (or previous) 9 buckets.

My first surprise was that it was harder than I expected! I shouldn't have been surprised :) Seriously, I thought that I could just wrap my existing view with the ViewFlipper and provide an index for 'paging'. I ended up implementing (hard-coding) 3 static pages with the intention of just ignoring the swipe if there weren't any next / previous screens. My second surprise was that I couldn't get the onFling / GestureDetector to fire. I thought I had grown a solid understanding of Android but sheesh - this should be trivial stuff.

Added to onCreate

mViewFlipper = (ViewFlipper) findViewById(;
mGestureDetector = new GestureDetector(new FlingGestureDetector());
mGestureListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
Log.d(getClass().getSimpleName(), "HERE onTouch");
if (mGestureDetector.onTouchEvent(event)) {
return true;
return false;

Then I added this inner class. Just a quick reminder, this doesn't currently work - I'm just recording the notes here.

class FlingGestureDetector extends SimpleOnGestureListener {
public boolean onFling(MotionEvent eventStart, MotionEvent eventEnd, float velocity, float unusedVelocity) {
Log.i(getClass().getSimpleName(), "onFling (" + eventStart + ", " + eventEnd + ", " + velocity + ")");

try {
if (Math.abs(eventStart.getY() - eventEnd.getY()) > FLING_MAX_DEVIATION) {
Log.d(MainActivity.class.getSimpleName(), "onFling too much Y in motion, not fling");
return false;
if (eventStart.getX() - eventEnd.getX() > FLING_MIN_DISTANCE && Math.abs(velocity) > FLING_MIN_VELOCITY) {
mViewFlipper.setInAnimation(AnimationUtils.makeInAnimation(MainActivity.this, true));
mViewFlipper.setOutAnimation(AnimationUtils.makeOutAnimation(MainActivity.this, true));
} else if (eventEnd.getX() - eventStart.getX() > FLING_MIN_DISTANCE && Math.abs(velocity) > FLING_MIN_VELOCITY) {
mViewFlipper.setInAnimation(AnimationUtils.makeInAnimation(MainActivity.this, false));
mViewFlipper.setOutAnimation(AnimationUtils.makeOutAnimation(MainActivity.this, false));
} catch (Exception e) {
Log.w(MainActivity.class.getSimpleName(), "onFling ignoring unexpected exception: " + e);
return false;

OnTouchListener mGestureListener;

* Most people will probably just have the 1 page of buckets but for the
* people lucky enough to have more than 9 / 12 / whatever the number is,
* they can fling thru the pages.
private int mViewIndex = 0;

Blah blah blah - just a distraction. I need to get back to fixing sync'ing and adding buckets.

No comments: