I'm writing my own image viewer that enables users to swipe left\right to see the next\previous image. I want to animate the image change according to the fling velocity.
To detect a fling gesture and its velocity, I followed this basic gesture detection and did as the accepted answer suggested:
public class SelectFilterActivity extends Activity implements OnClickListener { 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; private GestureDetector gestureDetector; View.OnTouchListener gestureListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* ... */ // Gesture detection gestureDetector = new GestureDetector(this, new MyGestureDetector()); gestureListener = new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { return gestureDetector.onTouchEvent(event); } }; } class MyGestureDetector extends SimpleOnGestureListener { @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; // right to left swipe if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { // nothing } return false; } } The problem is that I get different velocity values (velocityX & velocityY) for different Android devices with same density. Basically it means that in one device the swipe feels slow and not-sensitive, and other devices feels too sensitive.
I thought it might have something to do with the "default" maximum velocity on the device, that can be fetched using -
ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity() The results on different devices with same density aren't the same as expected:
Samsung S I 480x800 density 1.5 Android 2.1 getScaledMinimumFlingVelocity(): 75 getScaledMaximumFlingVelocity(): 3600 ViewConfiguration.MAXIMUM_FLING_VELOCITY = 4000 HTC Desire 480x800 density 1.5 Android 2.3.3 getScaledMinimumFlingVelocity(): 75 getScaledMaximumFlingVelocity(): 6000 ViewConfiguration.MAXIMUM_FLING_VELOCITY = 4000 Samsung S III mini 480x800 density 1.5 Android 4.1 getScaledMinimumFlingVelocity(): 75 getScaledMaximumFlingVelocity(): 12000 ViewConfiguration.MAXIMUM_FLING_VELOCITY = 8000 You can also see that ViewConfiguration has 2 different values for MAXIMUM_FLING_VELOCITY in Android below 4.0 and above.
How come different devices with same density and almost same api level don't have the same max velocity? How can I get the same experience on different devices when a user makes a swipe gesture? Can I use the max velocity data to make a uniform experience across all Android devices?