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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1967039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:58:18  来源:igfitidea点击:

OnClickListener - x,y location of event?

android

提问by Mark

I have a custom view derived from View. I'd like to be notified when the view is clicked, and the x,y location of where the click happened. Same for long-clicks.

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

Looks like to do this, I need to override onTouchEvent(). Is there no way to get the x,y location of the event from an OnClickListenerinstead, though?

看起来要这样做,我需要覆盖onTouchEvent(). 但是,有没有办法从 an 获取事件的 x,y 位置OnClickListener

If not, what's a good way of telling if a motion event is a 'real' click vs a long-click etc? The onTouchEventgenerates many events in rapid succession etc.

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

回答by Vering

Thank you. That was exactly what I was looking for. My code now is:

谢谢你。这正是我正在寻找的。我现在的代码是:

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;
        }
    });

which does precisely what Mark asked for...

这正是马克所要求的......

回答by Suragch

Full example

完整示例

The other answers are missing some details. Here is a full example.

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

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);
        }
    };
}

Summary

概括

  • Add a class variable to store the coordinates
  • Save the X,Y coordinates using an OnTouchListener
  • Access the X,Y coordinates in the OnClickListener
  • 添加一个类变量来存储坐标
  • 使用一个保存 X,Y 坐标 OnTouchListener
  • 访问 X,Y 坐标 OnClickListener

回答by Tom R

Override onTouchEvent(MotionEvent ev)

覆盖 onTouchEvent(MotionEvent ev)

Then you can do:

然后你可以这样做:

ev.getXLocation()

Or something like that. Have a butches.

或类似的东西。有一个屠夫。

回答by Vitalii Malyi

You can make an extension function in Kotlin, like this:

您可以在 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)
    }
}

If you need a long click - just replace setOnClickListener

如果您需要长按 - 只需更换 setOnClickListener

I use getLocationOnScreen()because I need coordinates for RecyclerView's ViewHolder

我使用getLocationOnScreen()是因为我需要 RecyclerView 的 ViewHolder 坐标