安装html
yarn add react-native-gesture-handler
link到原生项目中react
react-native link react-native-gesture-handler
官方文档看的难受。React Native Gesture Handler 官网文档git
更加的流畅、可靠。github
react-native自带的PanResponder手势监视器由JS响应器系统控制而react-native-gesture-handler是在UI线程中识别和跟踪手势。react-native
若使用RN官方提供的手势管理在与发生在主线程上的触摸交互(如iOS滑块或任何滚动视图)时,常常会遇到问题。==因为主线程必须同步决定JS或滚动视图是否应该成为响应器,而JS只能异步响应并不能当即拒绝Native事件的响应,致使手势操做被这些Native组件劫持。==异步
ps: 上面提到的JS不能当即拒绝Native事件的响应对应PanResponder中的onPanResponderTerminationRequest方法,当该方法返回false时表示拒绝其余组件响应当前的手势。ide
问题场景示例:this
详情react-native项目中的这个issue:How to stopPropagation touch event线程
我解决这个问题过程: 如何在RN的可滚动组件内设置一个禁止滚动的区域指针
组件通用属性、方法 Common handler properties
enabled:是否响应手势操做。 shouldCancelWhenOutside:当前手势离开当前组件区域时是否进入CANCELLED或FAILD状态。 simultaneousHandlers waitFor:等待其余事件结束时才响应手势操做 hitSlop:能够控制视图区域的哪一个部分来开始识别手势。与View组件的hitSlop相似 onGestureEvent:手势ACTIVE状态时执行的回调 onHandlerStateChange:手势状态改变时的回调
事件参数
onHadlerStateChange与onGestureEvent回调的参数event(主要用到的就是nativeEvent属性)
//event的属性声明 interface event { nativeEvent: nativeEvent //... } //nativeEvent的属性声明 interface nativeEvent { absoluteX: number //相对于根视图,指针的当前位置的X坐标(当放置多个手指时的手指或前导指针)。 absoluteY: number //相对于根视图,指针的当前位置的Y坐标(当放置多个手指时的手指或前导指针)。 handlerTag: number numberOfPointers: number //表示当前放置在屏幕上的指针(手指)的数量。 state: number //手势处理程序的当前状态 translationX: number //手势开始到目前为止在水平方向上的移动距离。它与PanResponder中的dx相似 translationY: number //手势开始到目前为止在垂直方向上的移动距离。 velocityX: number //水平移速 velocityY: number //垂直移速 x: number //当前手势位置相对于附加PanGestureHandler的视图的X y: number //当前手势位置相对于附加PanGestureHandler的视图的Y }
手势操做过程当中,react-native-gesture-handler提供Handlers组件的State会不断变化,开发者根据State来响应不一样状态下的操做。详情查看Handler State
说明 | PanGestureHandler | PanResponder |
---|---|---|
是否声明成为触摸手势响应者或是否声明成为移动手势的响应者 | - | onStartShouldSetPanResponder ,onMoveShouldSetPanResponder |
触摸手势开始 | onHadlerStateChange, State.BEGAN | onPanResponderGrant |
手势移动过程当中执行的回调 | onHadlerStateChange, onGestureEvent, State.ACTIVE | onPanResponderMove |
手势释放 | onHadlerStateChange, State.END或State.FAILED | onPanResponderRelease |
是否将响应手势的操做交给其余组件 | - | onPanResponderTerminationRequest |
手势操做被其余组件或事件打断后的回调 | - | onPanResponderTerminate |
使用对比:
PanGestureHandler
import {PanGestureHandler, State} from 'react-native-gesture-handler' //... <PanGestureHandler onHadlerStateChange = ({nativeEvent}) => { switch (nativeEvent.state) { case State.UNDETERMINED: console.log('等待手势') break; case State.BEGAN: console.log('手势开始') break; case State.CANCELLED: console.log('手势取消') break; case State.ACTIVE: console.log('手势活跃') break; case State.END: console.log('手势结束') break; case State.FAILED: console.log('失败') break; default: console.log('其余') break; } } onGestureEvent = ({ nativeEvent }) => { } > <Animated.View //... > </Animated.View> </PanGestureHandler>
PanResponder
import {PanResponder} from 'react-native' <Animated.View { ...PanResponder.create({ onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder, onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder, onPanResponderGrant: this._handlePanResponderGrant, onPanResponderMove: this._handlePanResponderMove, onPanResponderRelease: this._handlePanResponderEnd, onPanResponderTerminationRequest: this._handlePanResponderRequestEnd, onPanResponderTerminate: this._handlePanResponderEnd, }).panHandlers } > </Animated.View>