I had to use some custom onTouchEvent listener, and use a VelocityTracker to determine the distance of the inerce movement. Then I simply use a translate animator and override onAnimationEnd to set the actual view margins to the new place, and that's it :)
Inertial movement of drag and drop
-
30-05-2022 - |
题
I'm working on a Drag and Drop code, so far it works fine, but I need it to be able to recognize and act based on the speed and direction of the finger swipe (keep moving even if finger is already up, aka adding inertia). A better example of this would be facebook chatheads:
解决方案
其他提示
use a custom on swipe touch listner
public class OnSwipeTouchListener implements OnTouchListener {
private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
public boolean onTouch(final View view, final MotionEvent motionEvent) {
return gestureDetector.onTouchEvent(motionEvent);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public boolean onSwipeRight() {
return false;
}
public boolean onSwipeLeft() {
return false;
}
public boolean onSwipeTop() {
return false;
}
public boolean onSwipeBottom() {
return false;
}}
you can set your own values for SWIPE_THRESHOLD and SWIPE_VELOCITY_THRESHOLD
you can implement it by using the following code
findViewById(R.id.inner_content).setOnTouchListener(new OnSwipeTouchListener(){
public boolean onSwipeTop() {
Toast.makeText(SampleActivity.this, "top", Toast.LENGTH_SHORT).show();
return true;
}
public boolean onSwipeRight() {
Toast.makeText(SampleActivity.this, "right", Toast.LENGTH_SHORT).show();
return true;
}
public boolean onSwipeLeft() {
Toast.makeText(SampleActivity.this, "left", Toast.LENGTH_SHORT).show();
return true;
}
public boolean onSwipeBottom() {
Toast.makeText(SampleActivity.this, "bottom", Toast.LENGTH_SHORT).show();
return true;
}
});
you can use this piece of code by overriding SimpleOnGestureListener
package com.ViewFlipperDemo;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.OnTouchListener;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ViewFlipper;
//import com.ViewFlipperDemo.ViewFlipperSampleActivity.MyGestureDetector;
public class FlipActivity extends Activity {
private static final int SWIPE_MIN_DISTANCE = 60;
private static final int SWIPE_THRESHOLD_VELOCITY = 100;
private ViewFlipper vf;
private Context mContext;
private final GestureDetector detector = new GestureDetector(
new MyGestureDetector());
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return true;
}
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Configuration config = getResources().getConfiguration();
config.hardKeyboardHidden=1;
mContext = this;
vf = (ViewFlipper) this.findViewById(R.id.vfShow);
vf.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(final View view, final MotionEvent event) {
detector.onTouchEvent(event);
return true;
}
});
vf.addView(addImageView(R.drawable.scott));
vf.addView(addImageView(R.drawable.ricardo));
}
View addImageView(int resId) {
ImageView iv = new ImageView(this);
iv.setImageResource(resId);
return iv;
}
class MyGestureDetector extends SimpleOnGestureListener {
GestureLibrary mLibrary;
Canvas cv=new Canvas();
Paint pp=new Paint();
public boolean onDoubleTap(MotionEvent e1){
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
/* mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
if (!mLibrary.load()) {
finish();
}
GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener((OnGesturePerformedListener) this);
*/pp.setColor(Color.RED);
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
cv.drawLine(e1.getX(), e1.getY(), e2.getX(), e1.getY(),pp);
Toast.makeText(FlipActivity.this,"jj",
Toast.LENGTH_SHORT).show();
// vf.setInAnimation(AnimationUtils.loadAnimation(mContext,R.anim.left_in));
// vf.setOutAnimation(AnimationUtils.loadAnimation(mContext,R.anim.left_out));
// vf.showNext();
return true;
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//Toast.makeText(FlipActivity.this,"hi",
// Toast.LENGTH_SHORT).show();
cv.drawLine(e1.getX(), e1.getY(), e2.getX(), e1.getY(),pp);
// vf.setInAnimation(AnimationUtils.loadAnimation(mContext,R.anim.right_in));
// vf.setOutAnimation(AnimationUtils.loadAnimation(mContext,R.anim.right_out));
// vf.showPrevious();
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
}
不隶属于 StackOverflow