蒦嗳伱 发表于 2015-5-12 11:14:29

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的人也是参考了一些游戏框架的消息处理机制的。
页: [1]
查看完整版本: Windows Phone 7 学习流程攻略(三)