React Native:手势响应系统





在移动设备上的手势识别要比网页版复杂的多。 简单的一个触碰,就会根据不同应用,用户的使用意图,分成好几个阶段。例如:应用需要判断出来这个触摸是上下滚动,还是在小工具之间滑动,或是敲击。有些甚至可以在触碰的过程中发生变化。还有一些同时发生的触碰。


触碰响应系统就需要组件能够和这些触碰互动交流,而不需要再为他们的父类或是继承的子类开发更多的代码。这个系统是在 ResponderEventPlugin.js里面完成的,这文件本身也有一些更详细的介绍文档。

来练习一把


用户在使用原生应用与 web apps 时,用户体验绝然不同, 这也是一个很大的原因,大家都要求开发原生应用。每一个动作都应该具有下列的属性:

  • 回馈/高亮显示: 告诉用户谁在处理他们的手势命令,同时也展示出来一旦停止了手势,会发生什么。
  • 可以取消:当做一个动作时,用户可以在动作做到一半的时候取消掉,取消的方式就是把手指移开,而无须其它更多操作。

这些属性会让用户在使用应用的时候,感觉更舒服些,因为他可以让用户放心大胆的使用应用,而无须担心犯任何错误。

TouchableHighlight 和 Touchable*


响应系统的使用相对来说比较困难。所以我们提供了一个抽象的类来继承了响应系统: Touchable, 该类就是给那些可以敲击的组件使用。这个使用的是响应系统,同时也可以让你很轻松的配置敲击交互。当你要使用按钮或是网页链接时,记得调用 TouchableHighlight 类。

响应器的生命周期


一个视图在继承了正确的协商方式后,就可以变成一个触碰响应器。 这里有两个方法可以请求视图是否想要成为响应器:



  • View.props.onStartShouldSetResponder: (evt) => true, 该语句会询问视图,是否在触碰动作开始后就变成响尖器?
  • View.props.onMoveShouldSetResponder: (evt) => true:该语句会在该视图还不是响应器时,在执行的每一个触碰动作,都会去询问视图:是否现在想变成响应式的触碰?


如果视图返回来的是 True,表示他想成为响应器,那么接下来两件事中的某一个将会发生:


  • View.props.onResponderGrant: (evt) => {}: 现在视图就会开始响应触碰事伯。 也会在这个时间向用户展示接下来会发生什么。
  • View.props.onResponderReject: (evt) => {} :表示现在有其他的组件正在做为响应器执行任务,这会儿还没有被释放出来。




如果视图正在响应,那么下面的句柄会被调用到:



  • View.props.onResponderMove: (evt) => {}: 用户正在移动手指
  • View.props.onResponderMove: (evt) => {}: 表示触碰动作结束时关系,比方说: touchup.
  • View.props.onResponderTerminationRequest: (evt) => true: 有其他的组件想要成为响应器。那么当前做为响应器的视图是否愿意释放?返回 true就表示愿意释放。
  • View.props.onResponderTerminate: (evt) => {}: 表示响应器的权限已经从视图身上拿走了。有可能是被其它视图通过调用:onResponderTerminationRequest 后抢走了,也有可能被操作系统不打招呼,直接拿走。(在 iOS系统里就是发生在控制中心或是通知中心)。



evt  算是一个合成的触碰事件,他主要有下面的一些形式:



NativeEvent:
  • changedTouches: 因为上一个事件引起了所有触碰事件的数组发生了变化。
  • identifier:  触碰的 ID.
  • locationX: 相对于事件来说,触碰的 X 位置
  • locationY: 相对于事件来说,触碰的Y位置
  • pageX: 相对于屏幕来说,触碰的X位置
  • pageY: 相对于屏幕来说,触碰的 Y位置
  • target: 组件的节点ID正在接收触碰事件
  • timestamp: 触碰的时间标识,对于速度计算特别有用。
  • touches: 屏幕上所有当前触碰的数组




捕获 ShouldSet 句柄



onStartShouldSetResponder onMoveShouldSetResponder 的调用是使用冒泡模式,在最深处的节点最先被调用。 这也就意味着当多视图模式在*ShouldSetResponder 句柄返回为 true 时,最深的控件将成为响应器。 这种设计在大多数情况下是可取的,这样才能保证所有的控制和按钮是可用的。

但在有些特别情况,某些父类更想变成响应器。 这种情况就可以通过捕获位相来处理了。 在响应系统利用冒泡模式赋值给最深的组件之前,先捕获位相,调用:on*ShouldSetResponderCapture . 所以现在如果某个父类视图想要阻止他的子类在触碰开始就变成了响应器,他应该拥用 onStartShouldSetResponderCapture 句柄,并返回 true.

  • View.props.onStartShouldSetResponderCapture: (evt) => true,
  • View.props.onMoveShouldSetResponderCapture: (evt) => true,


PanResponder


对于高阶的手势说明,请参照: PanResponder

不深思则不能造于道。不深思而得者,其得易失。

名人名言- 曾国藩
  • By 优联实达
  • 2015-10-30
  • 2863
  • 公司新闻,网站开发,网站设计,UI