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:

enter image description here

有帮助吗?

解决方案

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 :)

其他提示

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;
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top