TapGestureHandler - react-native
2019-04-03 本文已影响0人
JamesSawyer
文档来源:
分离类型handler, 点击手势用来识别一个或多个手指触摸屏幕。这些手势中涉及的手指不得从初始触摸点显著的移动。可配置的:
- 手指必须触摸屏幕的次数
- 允许的距离(allowable distance)
例如,可以用来检测是单次点击,还是双击,还是连续3次点击
如果要激活handler,指定的手指的数量必须在适当的时间内以足够短的延迟点击视图达到指定的次数, 当handler被激活了,State立马变为 END
状态, 如果手指移动的距离超过了可允许的距离(allowable distance),则handler会识别失败
属性 (Properties)
属性除了公用属性外,下面是 PanGestureHandler
的特定属性:
-
minPointers
: handler被激活前放置的手指的数量 -
maxDurationMs
: 定义触摸后手指释放的时间,单位 ms -
maxDelayMs
:如果是多次点击,则下一次点击和上一次点击之间的最大时间间隔, 单位ms -
numberOfTaps
:定义激活handler需要的点击次数 -
maxDeltaX
:当手指沿着X轴移动给定的距离,handler如果还没有被激活,则识别将失败,单位 points -
maxDeltaY
:同上,针对Y轴方向 -
maxDist
:手指移动给定距离,handler如果还没有被激活,则识别将失败,单位 points,注意这个没有指定方向
事件数据 (event data)
除了基本的event属性,下面是 TapGestureHandler
特定的event属性:
-
x
:当前手指相对于handler给定的视图上的x坐标(多个手指时,以第一个手指触摸的点为准),单位 points -
y
: 同上,表示y坐标 -
absoluteX
:当前手指相对于handler 根视图 上的x坐标(多个手指时,以第一个手指触摸的点为准),推荐使用这个属性,而不是x
属性,因为这个属性是相对于根视图的坐标位置,不会受到当前视图transform之后的影响, 单位 points -
absoluteY
:同上,针对Y轴
示例 多次点击
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(); // 只能使用这种方式创建ref
_onHandlerStateChange = event => {
if (event.nativeEvent.state === State.ACTIVE) {
// 如果是激活状态
alert('按了很长时间了');
}
}
_onSingleTap = event => {
// event.nativeEvent 打印结果
// { x: 0,
// absoluteX: 0,
// absoluteY: 0,
// target: 89,
// handlerTag: 8,
// y: 0,
// oldState: 4,
// numberOfPointers: 0,
// state: 5 }
console.log('单次点击 event.nativeEvent', event.nativeEvent);
if (event.nativeEvent.state === State.ACTIVE) {
alert('点击了一次');
}
}
_onDoubleTap = event => {
console.log('双击 event.nativeEvent', event.nativeEvent);
if (event.nativeEvent.state === State.ACTIVE) {
alert('点击了2次');
}
}
// 单击Handler 使用 waitFor 属性 在 双击Handler 在 'BEGAN' 状态时,是不会被激活的
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>
)
}
}
这个示例用到的属性和前面的 PanGestureHandler
有点不一样:
- 用到了跨handlers之间的交互,这里使用到了
LongGestrueHandler
和TapGestureHandler
之间的嵌套使用的情况 - 使用到了
React.createRef()
创建ref,配合waitFor
属性一起使用的情况 -
onHanlderStateChange
的回调函数中,使用event.nativeEvent.state
来判断当前状态,而在PanGestureHandler
中使用的是event.nativeEvent.oldState
进行判断,注意2者之间的区别 -
waitFor
: 接收一个React ref 或者 refs数组 (只能使用React.ref()
创建),指向其它组件,设置了这个属性的Handler (假设是A)将在ref指向的handler(s) (B,C...) 的state在 'BEGAN' 时,A handler就不会激活