安裝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>