如何使用 OnTouchListener 获取对象的正确坐标(event.getX() / event.getY())

How to get correct coords(event.getX() / event.getY()) of Object with OnTouchListener

我有这个:

我真正想要的是通过对象的 coords(X,Y) 和 OnTouchListener(orange square 中间有点)。

所以问题是我想绘制图像的一部分,就像它在图像上显示的那样(红色方块“我想要”显示的区域)。
所以在这种情况下,例外的结果是(位图的一部分):

目前我正在这样做:

public boolean onTouch(View view, MotionEvent event) {

    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:

            Bitmap mBitmap = Bitmap.createBitmap(sourceBitmap,view.getX() - view.getWidth(),view.getY()-view.getHeight(),250,250);
            //other stuff to fill this portion of bitmap
            break;
    }

    return true;
}
}

这是不正确的。

我怎样才能做到这一点? 尝试了很多公式,但没有运气。有什么建议么?

PS 据我了解 event.getX()/event.getY() 越来越相对坐标(我不清楚,从带有触摸侦听器的图像视图对象(中心有点的橙色正方形)得到的坐标到底是什么),我的意思是它得到这个对象的 centerTop.Left 角(X,Y)) ?

抱歉,在寻找解决方案的更多细节时,我想我找到了它并且我在工作所以你可以试试这个:

使用 event.getX() 而不是 view.getX()view.getX() return 您正在触摸的视图的位置,而不是您感兴趣的触摸事件。

这是可能会反转的 Y 坐标。

所以event.getX()就是触摸事件的位置

event.getY() 是反转的 Y 位置,所以 getHeight() - event.getY() 会给你你想要的 Y 位置。

编辑

在MOTION_MOVE情况下getX和getY return是最近的并且保持着历史数据。我想最近的一张是最有价值的,因为那是你要画的地方。

在这种情况下,使用文档中的批处理引用:

批处理 - http://developer.android.com/reference/android/view/MotionEvent.html

For efficiency, motion events with ACTION_MOVE may batch together multiple movement samples within a single object. The most current pointer coordinates are available using getX(int) and getY(int). Earlier coordinates within the batch are accessed using getHistoricalX(int, int) and getHistoricalY(int, int). The coordinates are "historical" only insofar as they are older than the current coordinates in the batch; however, they are still distinct from any other coordinates reported in prior motion events. To process all coordinates in the batch in time order, first consume the historical coordinates then consume the current coordinates.

你必须像这样获取坐标,它会给你参考视图而不是屏幕的坐标。

                float xCord = event.getRawX()-v.getX();
                float yCord = event.getRawY()-v.getY();

所以解决这个问题很简单。
解决方案
我有一个带有 OnTouchListener 的对象(orange square)(例如,他是一个四边形,大小为 50dp Height/ 50dp Width).
所以 view.getX()/view.getY() 获取对象(具有 OnTouchListener)的相对坐标(中心)。
所以我需要的是:

//imageview parameters ,where i will show this part of bitmap
int Width = img.getWidth();
int Height = img.getHeight();
//after this,i make margin of my coords,via this simple formula -> Current Coord X - Width / 2 (same for Y)
 Bitmap mBitmap = Bitmap.createBitmap(sourceBitmap,view.getX() - Width / 2,view.getY()-Height / 2,Width,Height);  

仅此而已。
享受吧!

遗憾的是,如果您想真正解决视图范围内的事件,则没有简单的方法来解决这个问题。这仍然发生在某些硬件的 Android Pie 上。解决奇怪的触摸事件的唯一方法是比较最后 3 个事件,如果在 ACTION_MOVE 期间没有奇怪的移动,然后再渲染视图的位置。下面是在循环视图中检查事件时的示例。假设您创建了一个 new double[3] 临时变量:

  /**
     * This detects if your finger movement is a result of an actual raw touch event of if it's from a view jitter.
     * This uses 3 events of rotation as temporary storage so that differentiation between swapping touch events can be determined.
     *
     * @param newRotationValue
     */
    private boolean isRotationTouchEventConsistent(final double newRotationValue) {
        double evalValue = newRotationValue;

        if (Double.compare(newRotationStore[2], newRotationStore[1]) != 0) {
            newRotationStore[2] = newRotationStore[1];
        }
        if (Double.compare(newRotationStore[1], newRotationStore[0]) != 0) {
            newRotationStore[1] = newRotationStore[0];
        }

        newRotationStore[0] = evalValue;

        if (Double.compare(newRotationStore[2], newRotationStore[0]) == 0
                || Double.compare(newRotationStore[1], newRotationStore[0]) == 0
                || Double.compare(newRotationStore[2], newRotationStore[1]) == 0

                //Is the middle event the odd one out
                || (newRotationStore[0] > newRotationStore[1] && newRotationStore[1] < newRotationStore[2])
                || (newRotationStore[0] < newRotationStore[1] && newRotationStore[1] > newRotationStore[2])
        ) {
            return false;
        }
        return true;
    }