react-native-gesture-handler 使用

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

  1. 使用react-native-scroll-tab-view組件做爲導航,左右切換視圖。
  2. 在react-native-scroll-tab-view內嵌套了Slider組件或者其餘使用PanResponder手勢監視器實現了某些手勢操做。
  3. 使用時經常會出如今這些子組件作滑動操做時,觸發了react-native-scroll-tab-view組件的滑動的問題。

詳情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

與PanResponder對照

說明 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>
相關文章
相關標籤/搜索