【问题标题】:How to track a finger's location during movement?如何在移动过程中跟踪手指的位置?
【发布时间】:2019-04-30 04:36:50
【问题描述】:

假设有一个 ImageView (iv) 并且我在创建新的 GestureDetector (gs) gs = new GestureDetector(this.Context, listener) 时设置了iv.SetOnTouchListener(this),我如何在每 0.01 秒内定位手指的位置 (x,y)(如 一个例子)?

我应该使用哪个功能? OnFling? OnLongPress?

我不仅在谈论代码,而且还想了解如何实现这种在每 0.01 秒内获取手指位置的愿望。有什么想法吗?

【问题讨论】:

    标签: c# android xamarin ontouchlistener gesturedetector


    【解决方案1】:

    您可以实现View.IOnTouchListener 接口并将其作为侦听器应用到您的视图(在本例中为ImageView):

    View.IOnTouchListener 实现:

    注意:在此示例中使用 Java.Lang.Object 作为基类,但您可以使用任何基于Java.Lang.Object 的类(Activity 等...)

    public class MyTouch : Java.Lang.Object, View.IOnTouchListener
    {
        TimeSpan Milli10 = TimeSpan.FromMilliseconds(10);
        DateTime oldTime;
        public bool OnTouch(View v, MotionEvent e)
        {
            switch (e.Action)
            {
                case MotionEventActions.Down:
                    oldTime = DateTime.Now;
                    break;
                case MotionEventActions.Move:
                    if (DateTime.Now.Subtract(oldTime) > Milli10)
                    {
                        Console.WriteLine($"Touch {e.RawX} : {e.RawY} : tD: {DateTime.Now.Subtract(oldTime)}");
                        oldTime = DateTime.Now;
                    }
                    break;
                default:
                    break;
            }
            return true;
        }
    }
    

    然后,如果需要,只需实例化侦听器,并将其应用为 OnTouchListener

    imageView = FindViewById<ImageView>(Resource.Id.background);
    touch = new MyTouch();
    imageView.SetOnTouchListener(touch);
    

    更新:

    需要添加 LongPress、DoubleTap 等...,子类 GestureDetector.SimpleOnGestureListener 并将其作为内部类添加到您的 View.IOnTouchListener 实现中(这只是一种方式...)

    View.IOnTouchListener PLUS SimpleOnGestureListener:

    public class MyTouchPlusGestures : Java.Lang.Object, View.IOnTouchListener
    {
        readonly MyGestures myGestures = new MyGestures();
        readonly TimeSpan Milli10 = TimeSpan.FromMilliseconds(10);
        readonly GestureDetector gestureDetector;
        DateTime oldTime = DateTime.Now;
    
        internal class MyGestures : GestureDetector.SimpleOnGestureListener
        {
            public override void OnLongPress(MotionEvent e)
            {
                // do something with press
                base.OnLongPress(e);
            }
    
            public override bool OnDoubleTap(MotionEvent e)
            {
                // do something with tap
                return base.OnDoubleTap(e);
            }
        }
    
        public MyTouchPlusGestures(View view)
        {
            gestureDetector = new GestureDetector(view.Context, myGestures);
            view.SetOnTouchListener(this);
        }
    
        public bool OnTouch(View v, MotionEvent e)
        {
            if (!gestureDetector.OnTouchEvent(e))
            {
                // If the event is not handled in one of your gestures, 
                // fall through to the MotionEventActions switch.
                switch (e.Action)
                {
                    case MotionEventActions.Down:
                        oldTime = DateTime.Now;
                        break;
                    case MotionEventActions.Move:
                        if (DateTime.Now.Subtract(oldTime) > Milli10)
                        {
                            Console.WriteLine($"Touch {e.RawX} : {e.RawY} : tD: {DateTime.Now.Subtract(oldTime)}");
                            oldTime = DateTime.Now;
                        }
                        break;
                    default:
                        break;
                }
            }
            return true;
        }
    }
    

    现在只需将 View 传递给您的 MyTouchPlusGestures 实例,然后为您分配手势和触摸侦听器...

    imageView = FindViewById<ImageView>(Resource.Id.background);
    touch = new MyTouchPlusGestures(imageView);
    

    【讨论】:

    • 非常感谢 SushiHangover,知道你不会让我失望的。请多做几件事: 1. 为什么 tD 不是每 0.01 秒保持相同的值?因为if语句? 2. 如何检测每次计算之间的方向,以便知道将 PC 的光标放在哪里? 3. 如何检测此代码中的双击和长按? 4.为什么RawXRawY的值没有四舍五入?
    • @DanielReyhanian 查看我的手势更新.... 1) 频率。回调基于设备,因为它取决于显示器上的触摸扫描仪(某些设备具有 30hz 显示器,但现在(或即将推出)60、90、120hz 设备可用......并且它们的触摸扫描仪是同步的'd 到那个速度,其他不是)。 (使用您需要的那个)
    • @DanielReyhanian 如果您需要相对于视图本身而不是屏幕的坐标,是的,GetX|Y 就是您想要的。快乐编码?
    • 1) 这是一个长按事件,你在寻找什么“价值” 2) 使用OnSingleTapConfirmed 3) 不确定,需要再看一遍...
    • @DanielReyhanian 它返回一个 true|false 以确定您是否已提交该事件,否则将其传递给下一个事件侦听器。 "true if the OnGestureListener consumed the event, else false." 长按是一个“人为的”事件,因此在 View 的事件链中没有类似物,因此它不会传播到事件链,因此它有一个 void 返回。
    猜你喜欢
    • 2022-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 2018-08-20
    相关资源
    最近更新 更多