【问题标题】:Implementing GestureDetector to Drag, DoubleTap and singleTap a ImageView实现 GestureDetector 以拖动、DoubleTap 和 singleTap 一个 ImageView
【发布时间】:2015-09-29 04:41:27
【问题描述】:

我正在尝试实现一个 ImageView,它会对每个操作(拖动、双击和单击)产生不同的反应。我正在做的基于本教程: DoubleTap in android

我用来创建班级的:

public class MyIcon extends ImageView {

    GestureDetector gestureDetector;

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // creating new gesture detector
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    // skipping measure calculation and drawing

    // delegate the event to the gesture detector
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return gestureDetector.onTouchEvent(e);
    }


    private class GestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
        // event when double tap occurs
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            //A Toast just to see if it is working
            return true;
        }
        @Override
        public boolean onShowPress(MotionEvent e) {
            //A Toast just to see if it is working
            return true;
        }
    }
}

实例化:

private WindowManager windowManager;
private MyIcon myIcon;
private WindowManager.LayoutParams params;

windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new MyIcon(this);
    chatHead.setImageResource(R.mipmap.ic_launcher);

    params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSPARENT
    );

    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 100;

我使用了 setOnTouchListener(),它可以很好地进行拖动,但它不适用于 DoubleTap。

实现和实例化这个类以使其同时工作的正确方法是什么?

【问题讨论】:

    标签: java android android-imageview


    【解决方案1】:

    试试这个SimpleGestureFilter

    public class SimpleGestureFilter extends SimpleOnGestureListener {
    
        public final static int SWIPE_UP = 1;
        public final static int SWIPE_DOWN = 2;
        public final static int SWIPE_LEFT = 3;
        public final static int SWIPE_RIGHT = 4;
    
        public final static int MODE_TRANSPARENT = 0;
        public final static int MODE_SOLID = 1;
        public final static int MODE_DYNAMIC = 2;
    
        private final static int ACTION_FAKE = -13; // just an unlikely number
        private int swipe_Min_Distance = 100;
        private int swipe_Max_Distance = 350;
        private int swipe_Min_Velocity = 100;
    
        private int mode = MODE_DYNAMIC;
        private boolean running = true;
        private boolean tapIndicator = false;
    
        private Activity context;
        private GestureDetector detector;
        private SimpleGestureListener listener;
    
        public SimpleGestureFilter(Activity context, SimpleGestureListener sgl) {
    
            this.context = context;
            this.detector = new GestureDetector(context, this);
            this.listener = sgl;
        }
    
        public void onTouchEvent(MotionEvent event) {
    
            if (!this.running)
                return;
    
            boolean result = this.detector.onTouchEvent(event);
    
            if (this.mode == MODE_SOLID)
                event.setAction(MotionEvent.ACTION_CANCEL);
            else if (this.mode == MODE_DYNAMIC) {
    
                if (event.getAction() == ACTION_FAKE)
                    event.setAction(MotionEvent.ACTION_UP);
                else if (result)
                    event.setAction(MotionEvent.ACTION_CANCEL);
                else if (this.tapIndicator) {
                    event.setAction(MotionEvent.ACTION_DOWN);
                    this.tapIndicator = false;
                }
    
            }
            // else just do nothing, it's Transparent
        }
    
        public void setMode(int m) {
            this.mode = m;
        }
    
        public int getMode() {
            return this.mode;
        }
    
        public void setEnabled(boolean status) {
            this.running = status;
        }
    
        public void setSwipeMaxDistance(int distance) {
            this.swipe_Max_Distance = distance;
        }
    
        public void setSwipeMinDistance(int distance) {
            this.swipe_Min_Distance = distance;
        }
    
        public void setSwipeMinVelocity(int distance) {
            this.swipe_Min_Velocity = distance;
        }
    
        public int getSwipeMaxDistance() {
            return this.swipe_Max_Distance;
        }
    
        public int getSwipeMinDistance() {
            return this.swipe_Min_Distance;
        }
    
        public int getSwipeMinVelocity() {
            return this.swipe_Min_Velocity;
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
    
            final float xDistance = Math.abs(e1.getX() - e2.getX());
            final float yDistance = Math.abs(e1.getY() - e2.getY());
    
            if (xDistance > this.swipe_Max_Distance
                    || yDistance > this.swipe_Max_Distance)
                return false;
    
            velocityX = Math.abs(velocityX);
            velocityY = Math.abs(velocityY);
            boolean result = false;
    
            if (velocityX > this.swipe_Min_Velocity
                    && xDistance > this.swipe_Min_Distance) {
                if (e1.getX() > e2.getX()) // right to left
                    this.listener.onSwipe(SWIPE_LEFT);
                else
                    this.listener.onSwipe(SWIPE_RIGHT);
    
                result = true;
            } else if (velocityY > this.swipe_Min_Velocity
                    && yDistance > this.swipe_Min_Distance) {
                if (e1.getY() > e2.getY()) // bottom to up
                    this.listener.onSwipe(SWIPE_UP);
                else
                    this.listener.onSwipe(SWIPE_DOWN);
    
                result = true;
            }
    
            return result;
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            this.tapIndicator = true;
            return false;
        }
    
        @Override
        public boolean onDoubleTap(MotionEvent arg) {
            this.listener.onDoubleTap();
            ;
            return true;
        }
    
        @Override
        public boolean onDoubleTapEvent(MotionEvent arg) {
            return true;
        }
    
        @Override
        public boolean onSingleTapConfirmed(MotionEvent arg) {
    
            if (this.mode == MODE_DYNAMIC) { // we owe an ACTION_UP, so we fake an
                arg.setAction(ACTION_FAKE); // action which will be converted to an
                                            // ACTION_UP later.
                this.context.dispatchTouchEvent(arg);
            }
    
            return false;
        }
    
        static interface SimpleGestureListener {
            void onSwipe(int direction);
    
            void onDoubleTap();
        }
    
    }
    

    以这种方式在代码中使用

       private SimpleGestureFilter detector;
    
       detector = new SimpleGestureFilter(this, this);              
    

    改这个方法就行了

        @Override
        public boolean dispatchTouchEvent(MotionEvent me) {
            // Call onTouchEvent of SimpleGestureFilter class
            this.detector.onTouchEvent(me);
            return super.dispatchTouchEvent(me);
        }  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      相关资源
      最近更新 更多