在onLongPress之后继续onScroll事件

时间:2018-08-06 09:20:28

标签: android android-layout android-event android-gesture

有人知道如何结合onLongPress(MotionEvent e)onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)吗?想法是从onLongPress开始,但继续在某些视图中滑动。

我拥有的当前代码:

private class CustomListener implements View.OnTouchListener {

    ImagePreviewer imagePreviewer = new ImagePreviewer();

    private GestureDetector gestureDetector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener() {

        ImageView currentImageView;

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

            float x = e2.getX();
            float y = e2.getY() + mConstraintLayoutContainerCoordinates[1];

            currentImageView = getProperImage(mCurrentImagesNumberForPoll, (int) x, (int) y);

            if(currentImageView != null) {
                imagePreviewer.show(getActivity(), currentImageView);
            }

            return super.onScroll(e1, e2, distanceX, distanceY);
        }

        @Override
        public void onLongPress(MotionEvent e) {

            Log.d(TAG, "LONG PRESS");

            float x = e.getX();
            float y = e.getY() + mConstraintLayoutContainerCoordinates[1];
            currentImageView = getProperImage(mCurrentImagesNumberForPoll, (int) x, (int) y);
            if(currentImageView != null) {
                imagePreviewer.show(getActivity(), currentImageView);
            }

            super.onLongPress(e);
        }
    });

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            Log.d("TAG", "DOWN  or CANCEL ");
            imagePreviewer.hide();
        }
        gestureDetector.onTouchEvent(event);
        return true;
    }
}

事情是onScroll()被调用(当我在视图上滑动手指时)或onLongPress(),但是我想从onLongPress()开始,然后检测滑动,所以我可以选择适当的视图以显示相应。

3 个答案:

答案 0 :(得分:0)

GestureDetector.setIsLongpressEnabled(false):https://developer.android.com/reference/android/view/GestureDetector.html#setIsLongpressEnabled(boolean),但是通过这种方式可以松开onLongClick事件。但是,您可以通过计算从最初的“按下”触摸经过多少时间来实现onLongClick事件,然后在这段时间后提高代码/侦听器。

答案 1 :(得分:0)

我实现上述功能的方式有所不同。我使用onLongPress(MotionEvent e)来获取长按是否触发并创建一个标记 mLongClicked = true 一旦完成,我就会在onTouch()中自己滚动,因为一旦longPress被调用,onScroll就不会被框架调用。 这只是一个变通方案,而且完美无缺。

override fun onTouchEvent(event: MotionEvent?): Boolean {
        gestureDetector.onTouchEvent(event)    

        when (event.action) {
            MotionEvent.ACTION_MOVE -> {
                if (dragEvent) {
                    //Add on Move logic here for scroll
                    scrollListener.onDragEvent(DragEventType.move, event.x, event.y)
                    return false
                }
                if (mLongClicked) {
                    mLongClicked = false
                    dragEvent = true
                }
            }
            MotionEvent.ACTION_UP -> {
                if (dragEvent) {
                    //Add on Up logic here for scroll
                    scrollListener.onDragEvent(DragEventType.up, event.x, event.y)
                    dragEvent = false
                }
            }
        }
        return true
    }

并且onLongPress()看起来像这样:

override fun onLongPress(event: MotionEvent) {
            mLongClicked = true
            //Add on Down logic here for scroll
            zoomViewListener.onDragEvent(DragEventType.down, event.x, event.y)
        }

注意::我正在使用一个侦听器来滚动甚至不在外部查看和操作,您可以在此处自行执行。如果您考虑的是向下事件,那么请注意onLongPress()

与Java:p

相比,我更喜欢Kotlin

答案 2 :(得分:0)

GestureDetectorCompat在检测到onScroll之后阻止对onLongPress的呼叫。可以通过向检测器发送ACTION_CANCEL来取消屏蔽。

@Override
public void onLongPress(MotionEvent e) {
    isLongPressed = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (detector.onTouchEvent(event)) {
        return true;
    }

    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_MOVE:
            if (isLongPressed) {
                isLongPressed = false;
                MotionEvent cancel = MotionEvent.obtain(event);
                cancel.setAction(MotionEvent.ACTION_CANCEL);
                detector.onTouchEvent(cancel);
            }
            break;
    }
    return super.onTouchEvent(event);
}