zoukankan      html  css  js  c++  java
  • Windows 10 开发日记(三)-- 如何在手势开始之前判断手指数量

         这是我们在实际项目中经常要面临的问题,因为你很可能会出现这种需求:单手操作与双手操作的行为不同,在手势开始之时就需要知道到底是单手还是双手。

    方案一:     

          了解了这个需求之后,我迅速凭借经验,感觉在ManipulationStarting或者ManipulationStarted事件传入的参数中应该类似于e.GetPointers()类似的方法,用于获得当前有多少个手指在屏幕上。感觉三年的Windows 开发经验终于有了点小用,节省了我好多效率不免心生有预感。。。但是当寻找了半天之后,胸中顿时有几万只草泥马奔腾而过,不是说的是底层事件吗?底层事件连最简单的判断有几个手指头都不行么?TouchFrame才叫底层事件好吗???

         

        public class ManipulationStartedRoutedEventArgs : RoutedEventArgs, IManipulationStartedRoutedEventArgs
        {
            public ManipulationStartedRoutedEventArgs();
    
            public UIElement Container { get; }
            public ManipulationDelta Cumulative { get; }
            public System.Boolean Handled { get; set; }
            public PointerDeviceType PointerDeviceType { get; }
            public Point Position { get; }
    
            public void Complete();
        }
    

      各位请看,我不会冤枉好人的,根本就没有一个集合性的东西,这个Point倒是手指在屏幕上的接触点,但是这都是Started事件了好么?我要的是在Started之前就知道有几个手指头跟屏幕接触好么?

    方案二:

          抱着”微软虐我千百遍,我待微软如初恋"的心态,我继续寻找方案二。心想:如果我能获得这个容器,甚至我获取这个App所在的Frame,应该有暴露方法判断有多少个手指吧。具体的过程我就不说了,神马UIElement,Control,Frame,都没有啊,都没有。

    方案三:

         抱着“人在屋檐下,不得不低头”的心态,我继续寻找方案三,(毕竟技术是你微软的,项目是我的,还得继续啊,一万只草泥马又呼啸而来。。。),去MSDN上面扒了扒跟输入相关的知识点,终于发现了一个东西,并且是一个比较熟悉的东西:PointerPressed,中级事件,这个事件我们上篇已经做过实验了,它会在ManipulationStarting之前触发,就是说,如果我在这个事件触发之时,能获取手指的个数,那我就能解决这个问题了!(https://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj150606.aspx, 这篇文章详细介绍了Pointer相关的知识,有兴趣的朋友可以去看看,草泥马统统不见了,前途一片光明啊,哈哈哈)

         可以这么说,每一次点击都会触发一次PointerPressed事件,并且这个事件带来的参数能够获得接触点的信息,这个信息包含了PointerID,就是说,每一次点击,系统会标识这个接触点,松开后系统回收这个标记,那么我们本地可以实现一个字典,以PointerID为key,对应的Pointer为Value,那么在OnManipulationStarting事件中我就能判断是几个手指啦,说干就干

            private Dictionary<uint, Point?> _contacts; //与屏幕接触的点的集合
    
            /// <summary>
            /// 手指按下
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPointerPressed(PointerRoutedEventArgs e)
            {
                //if (e.Pointer.PointerDeviceType != Windows.Devices.Input.PointerDeviceType.Mouse)
                //{
                    _contacts[e.Pointer.PointerId] = e.GetCurrentPoint(this).Position;
                //}
                e.Handled = true;
            }
    
            /// <summary>
            /// 手指离开
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPointerReleased(PointerRoutedEventArgs e)
            {
                //if (e.Pointer.PointerDeviceType != Windows.Devices.Input.PointerDeviceType.Mouse)
                //{
                    if (_contacts.ContainsKey(e.Pointer.PointerId))
                    {
                        _contacts[e.Pointer.PointerId] = null;
                        _contacts.Remove(e.Pointer.PointerId);
                    }
                //}
                e.Handled = true;
            }
    
            /// <summary>
            /// 手指放上只会出发starting事件,要移动才开始触发started事件
            /// </summary>
            /// <param name="e"></param>
            protected override void OnManipulationStarted(ManipulationStartedRoutedEventArgs e)
            {
                int count = _contacts.Count;
    
                if (count == 1)
                {// 如果这时手指只有一根,则认为在对比模式
                    _viewController.OnManipulationStarted(e);
                }
                else if (count > 1)
                {// 如果手指超过一根,则认为在缩放模式下
                    e.Handled = true;
                }
            }
    

          哇哈哈哈哈,到了这个时候,功能做完了,是时候回过头来看看,为什么ManipulationStarting不能提供GetPoints()的方法。从实验的结果来看,ManipulationStarting应该还是只针对单次操作来说的,又或者说,ManipulationStarting只是一个“预备”的动作,并不能做很多事情。但是ManipulationDelta又可以判断双手操作中的:Scale,额,这个要在以后慢慢琢磨了。

            如果你也遇到了在操作之前判断手指的情况,这篇文章对你应该会有帮助。

            手势部分就到此,因为我在项目中也仅仅遇到了这些问题,不排除后续还有更复杂的情况出现,或者又扩展了很多其他问题。

            

      

  • 相关阅读:
    Android:CheckBox控件
    Android:RadioGroup,RadioButton
    Android:ImageView控件显示图片
    Spark:reduceByKey函数的用法
    HIve:beeline终端上在输错hive语句时,无论 Backspace还是delete 都删除不掉错误的语句,没有办法退格
    orchard-1.9.2-1.10.2汉化
    Hive:表1inner join表2结果group by优化
    hive:某张表进行分页
    hive:创建索引
    Android:后台给button绑定onClick事件、当返回项目到手机页面时提示是否退出APP
  • 原文地址:https://www.cnblogs.com/DinoWu/p/4528816.html
Copyright © 2011-2022 走看看