React Native Gesture Handler是什么?
React Native Gesture Handler
是Expo
公司推出的一个库,目的是替代React Native
自带的 Gesture Responder System。
React Native Gesture Handler
可以带来等多的手势操作和更好的性能,因为它使用了各个平台原生的touch handling system
来处理手势。
背景
移动设备
上的各种点击事件与web
上完全不一样, 在web
上,应用与用户交互是通过鼠标
,只能利用鼠标的单击
操作;而在移动设备
上,是通过手势系统
,用户是通过触摸屏幕
与应用交互的,这里的情况比web
上要复杂很多,比如 App 需要判断用户的触摸到底是在滚动页面,还是滑动一个 widget,或者只是一个单纯的点击。甚至还有多点同时触控的情况。
React Native
是通过 Gesture Responder System 来管理app中的手势操作
的整个生命周期的。
如何响应用户的触摸事件
-
pan
: 拖拽手势 -
pinch
: 捏合缩放手势 -
rotation
: 旋转手势
RN 自带的 gesture responder system
利用gesture responder system
,一个View
只需要要实现了一些定义好的方法,就可以响应触摸事件了:
- View.props.onStartShouldSetResponder: (evt) => true, - 在用户开始触摸的时候(手指刚刚接触屏幕的瞬间),是否愿意成为响应者?
- View.props.onMoveShouldSetResponder: (evt) => true, - 如果 View 不是响应者,那么在每一个触摸点开始移动(没有停下也没有离开屏幕)时再询问一次:是否愿意响应触摸交互呢?
如果 View 返回 true,并开始尝试成为响应者,那么会触发下列事件之一:
- View.props.onResponderGrant: (evt) => {} - View 现在要开始响应触摸事件了。这也是需要做高亮的时候,使用户知道他到底点到了哪里。
- View.props.onResponderReject: (evt) => {} - 响应者现在“另有其人”而且暂时不会“放权”,请另作安排。
如果 View 已经开始响应触摸事件了,那么下列这些处理函数会被一一调用:
- View.props.onResponderMove: (evt) => {} - 用户正在屏幕上移动手指时(没有停下也没有离开屏幕)。
- View.props.onResponderRelease: (evt) => {} - 触摸操作结束时触发,比如"touchUp"(手指抬起离开屏幕)。
- View.props.onResponderTerminationRequest: (evt) => true - 有其他组件请求接替响应者,当前的 View 是否“放权”?返回 true 的话则释放响应者权力。
- View.props.onResponderTerminate: (evt) => {} - 响应者权力已经交出。这可能是由于其他 View 通过onResponderTerminationRequest请求的,也可能是由操作系统强制夺权(比如 iOS 上的控制中心或是通知中心)。
手势响应系统
用起来可能比较复杂。所以RN
利用了手势响应系统
封装了一个抽象的Touchable实现(TouchableOpacity、TouchableHighlight等),用来做可触控
的组件,使得你可以简单地以声明的方式来配置触控处理。他们可以绑定4种不同的响应方法
- onPress
- onPressIn
- onPressOut
- onLonePress
而对于手指滑动(拖拽)、多点触控等操作,利用上面的Touchable
方法无法实现,于是RN
又在手势响应系统
的基础上封装了一个 PanResponder 来处理更复杂的手势操作。封装后的PanResponder 方法的抽象程度更高,使用起来也更加方便:
panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
console.log('evt', evt)
console.log('gestureState', gestureState)
},
onPanResponderMove: (evt, gestureState) => {
console.log('evt', evt)
console.log('gestureState', gestureState)
},
onPanResponderRelease: (evt, gestureState) => {
console.log('evt', evt)
console.log('gestureState', gestureState)
},
})
render() {
<View style={styles.container}
{...this.panResponder.panHandlers}
>
...
</View>
}
PanResponder
在手势响应系统的原生事件
之外提供了一个新的gestureState
对象,提供了更多实用的字段(具体可以看文档);并且handler
响应器回调函数是原来gesture responder system
中的回调函数的加强版本:
onMoveShouldSetPanResponder: (e, gestureState) => {...}
onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}
onStartShouldSetPanResponder: (e, gestureState) => {...}
onStartShouldSetPanResponderCapture: (e, gestureState) => {...}
onPanResponderReject: (e, gestureState) => {...}
onPanResponderGrant: (e, gestureState) => {...}
onPanResponderStart: (e, gestureState) => {...}
onPanResponderEnd: (e, gestureState) => {...}
onPanResponderRelease: (e, gestureState) => {...}
onPanResponderMove: (e, gestureState) => {...}
onPanResponderTerminate: (e, gestureState) => {...}
onPanResponderTerminationRequest: (e, gestureState) => {...}
onShouldBlockNativeResponder: (e, gestureState) => {...}
网友评论