zoukankan      html  css  js  c++  java
  • Windows Phone 7 学习流程攻略(三)

    今天介绍触摸屏点击

    从硬件设计上说Windows Phone 7至少可以接收4个手指的触摸事件。

    一、在XNA上的Low-Level触摸事件

    可以利用全局的TouchPanel class来的到输入事件。

    -----------------------------

    Tips:

    1. 调用静态的TouchPanel.GetCapabilities()方法返回TouchPanelCapabilities的可以的到系统的输入能力。

        TouchPanelCapabilities对象中:

               IsConnected表示触摸是否可用。

               MaximumTouchCount表示最多可响应几个触点。

    2. 在Update()函数中,调用TouchPanel.GetState()方法来的到TouchCollection对象来的到当前的按键情况。

    3. 得到的TouchCollection对象中有0到多个TouchLocation对象,包含单个触点对象的信息。

        TouchLocation对象中:

              TouchLocationState State:Pressed, Moved, Released

              Vector2 Position:表示触点针对左上角的位置

              int id:表示在一次触摸过程中的唯一标识(从按下开始分配这个ID,在抬起事件结束前这个ID不会变)

              bool TryGetPreviousLocation(out TouchLocation)方法,可以得到上一次刷新的触点对象。(可以用来算位移差值,没有上一个位置的话函数会返回false)

        注意:在Pressed事件过后,就算手指没有移动也会接收到Moved事件,直到手指抬起触发Released事件。

                如果点击得特别快在两次刷新之间完成了按下和抬起,是收不到Moved事件的。

                手指这个东东比较粗,有可能你按一下下会产生多个Pressed事件,处理的时候还要考虑按键区域的问题。不要重复计算多个区域的好。

    ------------------------------

    二、XNA下的手势接口

    这个比刚才那个高级了。

    直接利用TouchPanel.EnabledGestures设置你需要监听的手势,然后在Update()中,通过查询属性TouchPanel.IsGestureAvailable,得到当前是否有需要的手势状态并做处理。

    ------------------------------

    Tips:

    1. TouchPanel.EnabledGestures可以设置的动作有Tap, DoubleTap, Flick, Hold, Pinch, PinchComplete, FreeDrag, HorizontalDrag, VerticalDrag 和 DragComplete,他们之间可以用与运算连接同时设置多个动作。

    2. 在Update()中读取手势的方法:

    protected override void Update(GameTime gameTime)
    {

        …

        while(TouchPanel.IsGestureAvailable)

        {

              //得到一个动作取样

              GestureSample gestureSample = TouchPanel.ReadGesture();

              if (gestureSample.GestureType == GestureType.Tap)

              {

                    //…………………………

              }

              else if (gestureSample.GestureType == ……….)

              {

                   //…………………………

              }

        }

    }

        注意:手势事件是在确实触发了这种事件后才执行的,因此Tap是在手指离开屏幕才处理的。

                有些手势会有前置动作,GestureSample中的Position2和Delta2就起了作用。

    ----------------------------

    三、在Silverlight上的Low-Level触摸事件

    在Silverlight上,可以通过静态事件Touch.FrameReported回调事件响应函数。

    --------------------------

    Tips:

    1. 将回调函数添加到事件中。

             Touch.FrameReported += OnTouchFrameReported;
        回调函数的实现类似于:

              void OnTouchFrameReported(object sender, TouchFrameEventArgs args) {
                …

              }

         TouchFrameEventArgs对象中包含:

                 GetTouchPoints(refElement) 返回一个 TouchPointCollection(也就是一组TouchPoint,参数传null的话,返回从左上角开始的所有触点内容)
                 GetPrimaryTouchPoint(refElement) 返回一个 TouchPoint(第一个触摸事件)
                 SuspendMousePromotionUntilTouchUp()禁止该事件被提升为鼠标事件,这个函数可有渊源等下详细介绍。

         GetTouchPoints和GetPrimaryTouchPoint返回的都是和TouchPoint相关的。

         那就先说说TouchPoint对象:

                  TouchAction Action:Down, Move, 和 Up.

                  Point Position:这个就是针对左上角的坐标了。

                  Size Size:触摸的区域大小(在WP7上没啥用)

                  TouchDeivce TouchDeivce:这个是个对象里面包含:int Id,从触点按下到抬起的唯一标识。UIElement DirectlyOver,按键底下的控件,也就是谁不幸被点了。

           SuspendMousePromotionUntilTouchUp(),禁止该时间被提升为鼠标事件,得解释一下,这个方法来自桌面的Silverlight,很多桌面程序只有鼠标按键,现在有触摸屏了,点一下触摸屏,一小下,就不好区分,这个事件是鼠标点的还是触控事件呢?这个函数就是在处理触控的时候防止同时触发鼠标的点击事件。因此,这个函数只能在,只有在处理第一个触摸事件,并且是在处理按下事件的时候才能调用。否则~~哼哼,会抛出异常。下面是个调用的例子。

    void OnTouchFrameReported(object sender, TouchFrameEventArgs args)


         TouchPoint primaryTouchPoint = args.GetPrimaryTouchPoint(null);

         //第一个触点,并且是按下事件
         if (primaryTouchPoint != null && primaryTouchPoint.Action == TouchAction.Down) 
         { 
             args.SuspendMousePromotionUntilTouchUp(); 
         }  
         …

    }

    -----------------------------

    四、操作事件(The Manipulation Events)

    Silverlight的高级操作接口。由三个事件组成ManipulationStart、ManipulationDelta、MannipulationCompleted。

    -----------------------------

    Tips:

    1. 在xaml中,这三个事件可以作为控件的属性添加到控件中。

    2. 三个方法ManipulationStart、ManipulationDelta、ManipulationCompleted,分别对应触摸操作的按下,移动,抬起三个事件。并且在出发ManipulationStart事件到ManipulationCompleted结束之间,就算有其他触摸,事件也不会被响应。

    3. 在回调中调用args.Complete()方法,会在执行完当前回调后立即触发ManipulationCompleted这个事件。

    4. 继承PhoneApplicationPage的窗口可以重载ManipulationStart、ManipulationDelta、ManipulationCompleted这三个方法。注意到在参数对象ManipulationStartedEventArgs args中,args.OriginalSource标志的是页面上触摸的控件。

    ----------------------------

    五、操作事件的执行路径

    现在,控件上可以有三个操作的回调,页面上可以有三个操作的重载。他们的执行路径会是什么样的呢?

    场景:

    在Page上有一个TextBlock,现在用户在TextBlock点了一下。

    以ManipulationStart事件为例:Silverlight框架会先执行TextBlock上的回调,然后执行Page重载的方法。

    但是当执行TextBlock上的回调时,设置了args.Handled为true,这样消息就不会传递给上层Page了。

    延伸:

    有个比较有意思的事情,TextBlock上的ManipulationStart执行时执行了args.Complete(),并且设置了args.Handled为true,同时不对ManipulationComplete中的args做操作。上层Page收不到OnManipulationStart的事件了,可是可以执行OnManipulationComplete重载。结论是这三个事件之间是并行没有关联的。

    其实也好理解,分别实现三个事件比三个事件关联容易多了,框架也更整齐。写Silverlight的人也是参考了一些游戏框架的消息处理机制的。

  • 相关阅读:
    C++-蓝桥杯-小数第n位[除法模拟]
    C++-蓝桥杯-合成植物[并查集][模板题]
    Overleaf操作
    三维向量差积,以及应用
    C++-蓝桥杯-分考场[2017真题][搜索][无向图染色]
    C++-POJ1094-Sorting It All Out[拓扑排序][邻接矩阵]
    C++-LUOGU1059-明明的随机数[堆排序]
    C++-快速排序[STL][快速排序][并归排序][堆排序]
    C++-蓝桥杯-波动数组[2014真题][DP优化]
    C++-蓝桥杯-[T1~T3][结果填空题][2015真题][水题]
  • 原文地址:https://www.cnblogs.com/biosli/p/1989120.html
Copyright © 2011-2022 走看看