检测触摸preSS VS长preSS VS运动?preSS、VS

2023-09-12 00:21:20 作者:风染叶子卿歌

我目前正在摆弄周围与Android编程,但我有一个小问题,检测不同的触摸事件,即正常的触摸preSS(屏幕和释放的preSS马上),长preSS(触摸屏幕并按住手指就可以了)和运动(拖动屏幕上的)。

I'm currently fiddling around with Android programming, but I have a small problem detecting different touch events, namely a normal touch press (press on the screen and release right away), a long press (touch the screen and hold the finger on it) and movement (dragging on the screen).

我想要做的是有一个形象(圆的)我的屏幕上,我可以随意拖动。然后,当我preSS一次(短/正常preSS)干杯想出了关于它的一些基本信息。当我长preSS它,一个AlertDialog与列表出现,选择不同的图像(圆形,矩形或三角形)。

What I wanted to do is have an image (of a circle) on my screen which I can drag around. Then when I press it once (short/normal press) a Toast comes up with some basic information about it. When I long press it, an AlertDialog with a list comes up to select a different image (circle, rectangle or triangle).

我做了一个自定义的视图与我自己的OnTouchListener检测的事件,并绘制图像中的OnDraw。该OnTouchListener.onTouch是这样的:

I made a custom View with my own OnTouchListener to detect the events and draw the image in onDraw. The OnTouchListener.onTouch goes something like this:

// has a touch press started?
private boolean touchStarted = false;
// co-ordinates of image
private int x, y;

public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    if (action == MotionEvent.ACTION_DOWN) {
        touchStarted = true;
    }
    else if (action == MotionEvent.ACTION_MOVE) {
        // movement: cancel the touch press
        touchStarted = false;

        x = event.getX();
        y = event.getY();

        invalidate(); // request draw
    }
    else if (action == MotionEvent.ACTION_UP) {
        if (touchStarted) {
            // touch press complete, show toast
            Toast.makeText(v.getContext(), "Coords: " + x + ", " + y, 1000).show();
        }
    }

    return true;
}

该问题是preSS不预期相当的工作,因为当我随便触摸屏幕它也检测运动的一点点,并取消该触摸preSS和图像周围移动来代替。

The problem is that the press doesn't quite work as expected, because when I casually touch the screen it also detects a tiny bit of movement and cancels the touch press and moves around the image instead.

我黑客围绕这一点我引入一个新的变量mTouchDelay这是我设置为0,ACTION_DOWN,增加移动,如果它是> = 3 MOVE我执行我的移动code。但我有一种感觉,这是不是真的要走的路。

I "hacked" around this a bit my introducing a new variable "mTouchDelay" which I set to 0 on ACTION_DOWN, increase in MOVE and if it's >= 3 in MOVE I execute my "move" code. But I have a feeling this isn't really the way to go.

我还没有找到如何检测长preSS。罪魁祸首真的是这似乎总是触发移动。

I also haven't found out how to detect a long press. The culprit really is the MOVE which seems to always trigger.

有关的东西我大概要一个例子,看到Android应用程序DailyStrip:它显示了一个连环画的图像。您可以拖动它,如果它过大的屏幕。您可以一次点击它对于某些控件,弹出和长preSS它的选项菜单。

For an example of what I roughly want, see the Android application "DailyStrip": it shows an image of a comic strip. You can drag it if it's too large for the screen. You can tap it once for some controls to pop-up and long press it for an options menu.

PS。我试图得到它的工作在Android 1.5,因为我的手机只能运行在1.5。

PS. I'm trying to get it to work on Android 1.5, since my phone only runs on 1.5.

推荐答案

这code可以点击和移动(拖拉,滚动)区别开来。在的onTouchEvent设置标志isOnClick,和最初的X,Y上ACTION_DOWN坐标。清除ACTION_MOVE标志(照看非故意运动常常检测其可以与一个阈const来解决)。

This code can distinguish between click and movement (drag, scroll). In onTouchEvent set a flag isOnClick, and initial X, Y coordinates on ACTION_DOWN. Clear the flag on ACTION_MOVE (minding that unintentional movement is often detected which can be solved with a THRESHOLD const).

private float mDownX;
private float mDownY;
private final float SCROLL_THRESHOLD = 10;
private boolean isOnClick;

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            mDownX = ev.getX();
            mDownY = ev.getY();
            isOnClick = true;
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            if (isOnClick) {
                Log.i(LOG_TAG, "onClick ");
                //TODO onClick code
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (isOnClick && (Math.abs(mDownX - ev.getX()) > SCROLL_THRESHOLD || Math.abs(mDownY - ev.getY()) > SCROLL_THRESHOLD)) {
                Log.i(LOG_TAG, "movement detected");
                isOnClick = false;
            }
            break;
        default:
            break;
    }
    return true;
}

有关龙preSS按照上面的建议,GestureDetector是要走的路。勾选此Q&功放; A:

For LongPress as suggested above, GestureDetector is the way to go. Check this Q&A:

Detecting长preSS采用Android