Android OnClickListener-x,y事件的位置?

Android OnClickListener-x,y事件的位置?,android,Android,我有一个从视图派生的自定义视图。我希望在单击视图时收到通知,以及单击发生的x、y位置。长时间点击也一样 看起来要执行此操作,我需要覆盖onTouchEvent()。但是,是否没有办法从OnClickListener获取事件的x,y位置 如果不是,那么什么是判断运动事件是“真实”点击还是长点击等的好方法?onTouchEvent快速连续生成许多事件等。覆盖onTouchEvent(MotionEvent ev) 然后你可以做: ev.getXLocation() 或者类似的。吃一块肉。谢谢。这正

我有一个从视图派生的自定义视图。我希望在单击视图时收到通知,以及单击发生的x、y位置。长时间点击也一样

看起来要执行此操作,我需要覆盖
onTouchEvent()
。但是,是否没有办法从
OnClickListener
获取事件的x,y位置

如果不是,那么什么是判断运动事件是“真实”点击还是长点击等的好方法?
onTouchEvent
快速连续生成许多事件等。

覆盖onTouchEvent(MotionEvent ev)

然后你可以做:

ev.getXLocation()

或者类似的。吃一块肉。

谢谢。这正是我想要的。我现在的代码是:

imageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                textView.setText("Touch coordinates : " +
                        String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
            }
            return true;
        }
    });
这正是Mark要求的…

完整示例 其他答案缺少一些细节。这里有一个完整的例子

public class MainActivity extends AppCompatActivity {

    // class member variable to save the X,Y coordinates
    private float[] lastTouchDownXY = new float[2];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // add both a touch listener and a click listener
        View myView = findViewById(R.id.my_view);
        myView.setOnTouchListener(touchListener);
        myView.setOnClickListener(clickListener);
    }

    // the purpose of the touch listener is just to store the touch X,Y coordinates
    View.OnTouchListener touchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            // save the X,Y coordinates
            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                lastTouchDownXY[0] = event.getX();
                lastTouchDownXY[1] = event.getY();
            }

            // let the touch event pass on to whoever needs it
            return false;
        }
    };

    View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // retrieve the stored coordinates
            float x = lastTouchDownXY[0];
            float y = lastTouchDownXY[1];

            // use the coordinates for whatever
            Log.i("TAG", "onLongClick: x = " + x + ", y = " + y);
        }
    };
}
总结
  • 添加一个类变量来存储坐标
  • 使用
    OnTouchListener保存X,Y坐标
  • 访问
    OnClickListener

您可以在Kotlin中创建一个扩展函数,如下所示:

fun View.setOnClickListenerWithPoint(action: (Point) -> Unit) {
    val coordinates = Point()
    val screenPosition = IntArray(2)
    setOnTouchListener { v, event ->
        if (event.action == MotionEvent.ACTION_DOWN) {
            v.getLocationOnScreen(screenPosition)
            coordinates.set(event.x.toInt() + screenPosition[0], event.y.toInt() + screenPosition[1])
        }
        false
    }
    setOnClickListener {
        action.invoke(coordinates)
    }
}
如果需要长时间单击,只需替换
setOnClickListener


我使用
getLocationOnScreen()
是因为我需要RecyclerView的视图持有者的坐标

嗨,Tom,是的,我们可以使用onTouchEvent,但是我们需要自己处理点击和长点击之间的区别,不是吗?他们不提供一种方法让你知道在OnClickListener中点击或长点击发生在哪里,这是没有意义的?谢谢,您需要做的就是记录上一个动作向上或动作移动事件的x&y位置,并在OnClick Listener@Romanguy中使用这些值,但您还必须计算两点之间的距离以确定单击。如果您在(0,0)处收到ACTION\u DOWN事件,然后在(100100)处收到ACTION\u UP事件,那绝对不是单击。@chx101,Rominguy的意思是(我认为)如果您只是在touchevent上记录最后一个ACTION\u UP坐标,那么这些坐标就是您可以在onclick中使用的坐标。然而,我认为实际上需要对视图进行子类化,否则onclick不会被调用。您还可以将点击作为手势检测器进行检测,如在回答中所述。这些坐标是视图的本地坐标吗?onTouch处理程序是否应该返回
false
,这样它就不会阻止触摸事件?(View.OnTouchListener.onTouch如果侦听器已使用该事件,则返回true,否则返回false。)好吧,这并不是“精确”的,因为释放手指时会触发
OnClickListener
,所以在
操作中向上
但有限制:如果f.i.fling(滑动)执行手势后,
OnClickListener
未被激发,但仍将处理
ACTION\u UP
。我正在尝试在单击的坐标上写入文本。我尝试在坐标
(event.getX(),event.getY())
处写入文本,但它没有在正确的位置写入。我的问题是:可以使用点()代替2个空格的浮点数组。点的X和Y类型为整数。坐标是浮点值。如果我使用Point类,我想我会失去精度。。。。我是Android新手,可能我错过了什么。@mboada,你说得对。应该有办法避免onTouchListener,而只使用onClickListener。不知何故,ContextMenu不需要它。单击一个项目并以视图作为定位点显示菜单后,它知道将其放置在触摸位置附近的位置。请参见此处:。你知道怎么可能吗?如果是这样,请考虑在那里回答。