如何检测 canvas 上的点击和长按

How to detect click and longClick on canvas

您好,我正在 Android 开发一款战舰游戏,目前我正在尝试实施船舶定位 activity。

我有一个带有 onDraw 的自定义视图,代表您在其上放置船只的板。

我希望能够通过单击来旋转船只并通过长按来拖动船只。问题是我不能只使用 onClick 和 onLongClick,因为我需要知道 canvas 上的点击在哪里。我尝试使用 onTouch,但没有用。我也尝试过使用 GestureDetector,但它只是把所有东西都弄乱了。

你对如何处理这个逻辑有什么建议吗?

您将需要使用 View.OnTouchListener

  1. 使用 view.setOnTouchListener(listener).

  2. 将触摸侦听器设置为您的 canvas
  3. 实现你的触摸监听器。您将需要实施 onTouch(View v, MotionEvent event) 方法。在此方法中,您将有权访问触摸事件,并且您将能够决定是简单的单击、长按等,并执行适当的操作。

您可以在 SO 上的 answer 中阅读更多相关信息。

i need to know where was the click on the canvas

您有一个自定义视图,因此您可以轻松使用 GestureDetector.SimpleOnGestureListener。只需覆盖 CustomView 的 onTouchEvent() 并使用 GestureDetectoronLongPress。我建议您在 CustomView 本身内处理此问题,而不是在 ActivityFragment 中处理。这将使事情模块化。

您可以按照以下代码完成此操作:

CustomView.java

public class CustomView extends View {

        private GestureDetectorCompat mGestureDetector;
        private LongPressGestureListener longPressGestureListener;

        CustomView(Context context, AttributeSet attrs) {
            super(context, attrs);
            longPressGestureListener= new LongPressGestureListener(this);
            mGestureDetector = new GestureDetectorCompat(context, longPressGestureListener);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            mGestureDetector.onTouchEvent(event);
            // Handle any other event here, if not long press.
            return true;
        }
}

LongPressGestureListener.java

public class LongPressGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public void onLongPress(MotionEvent e) {
            super.onLongPress(e);
            // e will give you the location and everything else you want
            // This is where you will be doing whatever you want to.
            int eIndex = MotionEventCompat.getActionIndex(e);
            float eX = MotionEventCompat.getX(e, eIndex);
            float eY = MotionEventCompat.getY(e, eIndex);
            Log.d("X:Y = " + eX + " : " + eY);
        }

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
}