TapGestureHandler - react-native-gesture-handler

文檔來源:

分離類型handler, 點(diǎn)擊手勢(shì)用來識(shí)別一個(gè)或多個(gè)手指觸摸屏幕。這些手勢(shì)中涉及的手指不得從初始觸摸點(diǎn)顯著的移動(dòng)??膳渲玫模?/p>

  • 手指必須觸摸屏幕的次數(shù)
  • 允許的距離(allowable distance)

例如,可以用來檢測(cè)是單次點(diǎn)擊,還是雙擊,還是連續(xù)3次點(diǎn)擊

如果要激活handler,指定的手指的數(shù)量必須在適當(dāng)?shù)臅r(shí)間內(nèi)以足夠短的延遲點(diǎn)擊視圖達(dá)到指定的次數(shù), 當(dāng)handler被激活了,State立馬變?yōu)?END 狀態(tài), 如果手指移動(dòng)的距離超過了可允許的距離(allowable distance),則handler會(huì)識(shí)別失敗

屬性 (Properties)

屬性除了公用屬性外,下面是 PanGestureHandler 的特定屬性:

  • minPointers: handler被激活前放置的手指的數(shù)量
  • maxDurationMs: 定義觸摸后手指釋放的時(shí)間,單位 ms
  • maxDelayMs:如果是多次點(diǎn)擊,則下一次點(diǎn)擊和上一次點(diǎn)擊之間的最大時(shí)間間隔, 單位ms
  • numberOfTaps:定義激活handler需要的點(diǎn)擊次數(shù)
  • maxDeltaX:當(dāng)手指沿著X軸移動(dòng)給定的距離,handler如果還沒有被激活,則識(shí)別將失敗,單位 points
  • maxDeltaY:同上,針對(duì)Y軸方向
  • maxDist:手指移動(dòng)給定距離,handler如果還沒有被激活,則識(shí)別將失敗,單位 points,注意這個(gè)沒有指定方向

事件數(shù)據(jù) (event data)

除了基本的event屬性,下面是 TapGestureHandler特定的event屬性:

  • x:當(dāng)前手指相對(duì)于handler給定的視圖上的x坐標(biāo)(多個(gè)手指時(shí),以第一個(gè)手指觸摸的點(diǎn)為準(zhǔn)),單位 points
  • y: 同上,表示y坐標(biāo)
  • absoluteX:當(dāng)前手指相對(duì)于handler 根視圖 上的x坐標(biāo)(多個(gè)手指時(shí),以第一個(gè)手指觸摸的點(diǎn)為準(zhǔn)),推薦使用這個(gè)屬性,而不是 x屬性,因?yàn)檫@個(gè)屬性是相對(duì)于根視圖的坐標(biāo)位置,不會(huì)受到當(dāng)前視圖transform之后的影響, 單位 points
  • absoluteY:同上,針對(duì)Y軸

示例 多次點(diǎn)擊

import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';
import { LongPressGestureHandler, ScrollView, State, TapGestureHandler } from 'react-native-gesture-handler';

import LoremIpsum from '../common';

const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
    paddingHorizontal: 10,
    paddingVertical: 20,
  },
  box: {
    width: 150,
    height: 150,
    backgroundColor: '#211234',
  }
})

class PressBox extends PureComponent {
  doubleTapRef = React.createRef(); // 只能使用這種方式創(chuàng)建ref
  _onHandlerStateChange = event => {
    if (event.nativeEvent.state === State.ACTIVE) {
      // 如果是激活狀態(tài)
      alert('按了很長(zhǎng)時(shí)間了');
    }
  }

  _onSingleTap = event => {
    // event.nativeEvent 打印結(jié)果
    // { x: 0,
    // absoluteX: 0,
    // absoluteY: 0,
    // target: 89,
    // handlerTag: 8,
    // y: 0,
    // oldState: 4,
    // numberOfPointers: 0,
    // state: 5 }
    console.log('單次點(diǎn)擊 event.nativeEvent', event.nativeEvent);
    if (event.nativeEvent.state === State.ACTIVE) {
      alert('點(diǎn)擊了一次');
    }
  }
  
  _onDoubleTap = event => {
    console.log('雙擊 event.nativeEvent', event.nativeEvent);
    if (event.nativeEvent.state === State.ACTIVE) {
      alert('點(diǎn)擊了2次');
    }
  }

  // 單擊Handler 使用 waitFor 屬性 在 雙擊Handler 在 'BEGAN' 狀態(tài)時(shí),是不會(huì)被激活的
  render() {
    return (
      <LongPressGestureHandler
        onHandlerStateChange={this._onHandlerStateChange}
        minDurationMs={800}
      >
        <TapGestureHandler
          onHandlerStateChange={this._onSingleTap}
          waitFor={this.doubleTapRef}
        >
          <TapGestureHandler
            ref={this.doubleTapRef}
            onHandlerStateChange={this._onDoubleTap}
            numberOfTaps={2}
          >
            <View style={styles.box} />
          </TapGestureHandler>
        </TapGestureHandler>
      </LongPressGestureHandler>
    )
  }
}


export default class MultiTapExample extends PureComponent {
  render() {
    return (
      <ScrollView style={styles.scrollView}>
        <LoremIpsum words={40} />
        <PressBox />
        <LoremIpsum />
      </ScrollView>
    )
  }
}

這個(gè)示例用到的屬性和前面的 PanGestureHandler 有點(diǎn)不一樣:

  • 用到了跨handlers之間的交互,這里使用到了 LongGestrueHandlerTapGestureHandler 之間的嵌套使用的情況
  • 使用到了 React.createRef() 創(chuàng)建ref,配合 waitFor 屬性一起使用的情況
  • onHanlderStateChange 的回調(diào)函數(shù)中,使用 event.nativeEvent.state 來判斷當(dāng)前狀態(tài),而在 PanGestureHandler 中使用的是 event.nativeEvent.oldState 進(jìn)行判斷,注意2者之間的區(qū)別
  • waitFor: 接收一個(gè)React ref 或者 refs數(shù)組 (只能使用 React.ref() 創(chuàng)建),指向其它組件,設(shè)置了這個(gè)屬性的Handler (假設(shè)是A)將在ref指向的handler(s) (B,C...) 的state在 'BEGAN' 時(shí),A handler就不會(huì)激活
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容