在视图的Ontouch方法中单击触摸检测

San*_*p R 16 android touch ontouchlistener

我在自定义视图的ontouch方法中需要单点触摸检测.我尝试在ACTION-DOWN和ACTION-UP中获取x和y值,在ACTION-UP中我给出了一个条件,即如果ACTIONDOWN和ACTION-UP中的X和Y值相等,则将其作为单击.

我的代码如下

@Override
public boolean onTouchEvent(MotionEvent ev) {
   if (!mSupportsZoom && !mSupportsPan) return false;

    mScaleDetector.onTouchEvent(ev);

    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        final float x = ev.getX();
        final float y = ev.getY();

        mLastTouchX = x;  //here i get x and y values in action down
        mLastTouchY = y;
        mActivePointerId = ev.getPointerId(0);

        break;
    }

    case MotionEvent.ACTION_MOVE: {
        final int pointerIndex = ev.findPointerIndex(mActivePointerId);
        final float x = ev.getX(pointerIndex);
        final float y = ev.getY(pointerIndex);

        if (mSupportsPan && !mScaleDetector.isInProgress()) {
            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;
            //mFocusX = mPosX;
            //mFocusY = mPosY;

            invalidate();
        }

        mLastTouchX = x;
        mLastTouchY = y;

        break;
    }

    case MotionEvent.ACTION_UP: {

        final float x = ev.getX();
        final float y = ev.getY();

        touchupX=x;   //here is get x and y values at action up
        touchupY=y; 

        if(mLastTouchX == touchupX && mLastTouchY == touchupY){  //my condition if both the x and y values are same .

            PinchZoomPanActivity2.tapped1(this.getContext(), 100); //my method if the singletap is detected

        }
        else{

        }

        mActivePointerId = INVALID_POINTER_ID;

        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        final int pointerId = ev.getPointerId(pointerIndex);
        if (pointerId == mActivePointerId) {

            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            mLastTouchX = ev.getX(newPointerIndex);
            mLastTouchY = ev.getY(newPointerIndex);
            mActivePointerId = ev.getPointerId(newPointerIndex);
        }
        break;
    }
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

但我不能完成它.我的意思是在我的方法的每个动作都被调用.即使actionup和actiondown的x和y值不相同.当我们用手指在屏幕上触摸时,我想我还需要为单声道放置一些范围.有人能建议我一些方法吗?

Dhi*_*dya 38

要在android中检测Single和Double Tap,我使用以下方法:

class GestureTap extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.i("onDoubleTap :", "" + e.getAction());
        return true;
   }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        Log.i("onSingleTap :", "" + e.getAction());
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

在GestureDetector的构造函数中使用它:

detector = new GestureDetector(this, new GestureTap());
Run Code Online (Sandbox Code Playgroud)

并在onTouch侦听器中添加以下代码

@Override
public boolean onTouchEvent(MotionEvent event) {

    detector.onTouchEvent(event);

    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • +1先生,谢谢您挽救了我的工作和生命。你是天使。另外要补充一点,这里是您可以覆盖的更多受支持手势的参考:https://developer.android.com/training/gestures/detector.html#detect。查看“检测手势”部分。 (2认同)
  • 非常感谢,这为我节省了大量时间!:D (2认同)

Dro*_*kas 13

为了完整性添加答案,如果有其他人到达这里:

你可以用GestureDetector一个OnTouchListener

final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
         //do something
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            super.onLongPress(e);
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return super.onDoubleTap(e);
        }
    });

 viewToTouch.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            return gestureDetector.onTouchEvent(event);
        }
    });
Run Code Online (Sandbox Code Playgroud)


Jon*_*Jon 8

我最近也遇到了同样的问题,并最终不得不实施去抖动以使其正常工作.它并不理想,但在我能找到更好的东西之前它是非常可靠的.

View.onClickListener对我来说更可靠,但不幸的是我需要来自OnTouchListener的MotionEvent.

编辑:删除了导致它在此处失败的多余代码

class CustomView extends View {

    private static long mDeBounce = 0;

    static OnTouchListener listenerMotionEvent = new OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if ( Math.abs(mDeBounce - motionEvent.getEventTime()) < 250) {
                //Ignore if it's been less then 250ms since
                //the item was last clicked
                return true;
            }

            int intCurrentY = Math.round(motionEvent.getY());
            int intCurrentX = Math.round(motionEvent.getX());
            int intStartY = motionEvent.getHistorySize() > 0 ? Math.round(motionEvent.getHistoricalY(0)) : intCurrentY;
            int intStartX = motionEvent.getHistorySize() > 0 ? Math.round(motionEvent.getHistoricalX(0)) : intCurrentX;

            if ( (motionEvent.getAction() == MotionEvent.ACTION_UP) && (Math.abs(intCurrentX - intStartX) < 3) && (Math.abs(intCurrentY - intStartY) < 3) ) {
                if ( mDeBounce > motionEvent.getDownTime() ) {
                    //Still got occasional duplicates without this
                    return true;
                }

                //Handle the click

                mDeBounce = motionEvent.getEventTime();
                return true;
            }
            return false;
        }
    };
}
Run Code Online (Sandbox Code Playgroud)