【发布时间】:2009-12-27 21:03:33
【问题描述】:
我有一个从 View 派生的自定义视图。我希望在单击视图时收到通知,以及单击发生位置的 x、y 位置。长按也是一样。
看起来要这样做,我需要覆盖onTouchEvent()。不过,有没有办法从OnClickListener 获取事件的 x,y 位置?
如果不是,那么有什么好方法可以判断动作事件是“真正的”点击还是长按等? onTouchEvent 快速连续生成许多事件等。
【问题讨论】:
标签: android
我有一个从 View 派生的自定义视图。我希望在单击视图时收到通知,以及单击发生位置的 x、y 位置。长按也是一样。
看起来要这样做,我需要覆盖onTouchEvent()。不过,有没有办法从OnClickListener 获取事件的 x,y 位置?
如果不是,那么有什么好方法可以判断动作事件是“真正的”点击还是长按等? onTouchEvent 快速连续生成许多事件等。
【问题讨论】:
标签: android
谢谢。这正是我想要的。我现在的代码是:
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 要求的...
【讨论】:
false 这样它就不会阻止触摸事件吗? (View.OnTouchListener.onTouch 如果监听器已经消费了事件,则返回 true,否则返回 false。)
OnClickListener 在手指释放时被触发,所以在ACTION_UP 中但有限制:如果 f.i.执行了滑动(滑动)手势,然后OnClickListener 不会被触发,但ACTION_UP 仍将被处理。
(event.getX(), event.getY()) 处写文字,但它没有写在正确的位置。
其他答案缺少一些细节。这是一个完整的例子。
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 中的 X,Y 坐标
【讨论】:
覆盖 onTouchEvent(MotionEvent ev)
那么你可以这样做:
ev.getXLocation()
或者类似的东西。吃肉吧。
【讨论】:
你可以在 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 的 ViewHolder 的坐标
【讨论】: