react-native-gesture-handler 使用


安裝

yarn add react-native-gesture-handler

link到原生項目中

react-native link react-native-gesture-handler 

為什么寫這個文檔

官方文檔看的難受。React Native Gesture Handler 官網文檔

為什么要使用這個庫

更加的流暢、可靠。

react-native自帶的PanResponder手勢監視器由JS響應器系統控制而react-native-gesture-handler是在UI線程中識別和跟蹤手勢。

若使用RN官方提供的手勢管理在與發生在主線程上的觸摸交互(如iOS滑塊或任何滾動視圖)時,經常會遇到問題。由於主線程必須同步決定JS或滾動視圖是否應該成為響應器,而JS只能異步響應並不能立即拒絕Native事件的響應,導致手勢操作被這些Native組件劫持。

ps: 上面提到的JS不能立即拒絕Native事件的響應對應PanResponder中的onPanResponderTerminationRequest方法,當該方法返回false時表示拒絕其他組件響應當前的手勢。

問題場景示例:

  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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM