在 React Native 中同时使用双击和单击
Use double click and single click simultaneously in react native
Hi, Thanks in advance, am using the Double click Component and it
works well for double click event. But I need to get an action when
user perform a single click. What the work around for this issue.
<DoubleClick onClick={(e) => this.hClick(value,e)}>
<View>
<Text>
{value.item}
</Text>
</View>
</DoubleClick>
取消双击,使用可触摸组件。将点击传递给函数,并使用定时器延迟
来判断是单击还是双击
我写了一个组件。
// @flow
import * as React from 'react';
import { TouchableOpacity } from 'react-native';
import type { PressEvent } from 'react-native/Libraries/Types/CoreEventTypes';
type Props = {
children?: any,
onSingleTap: (event: PressEvent) => void,
onDoubleTap: (event: PressEvent) => void,
};
const MAX_DOUBLE_TOUCH_DISTANCE = 20;
const MAX_DOUBLE_TOUCH_DELAY_TIME = 250;
class SingleDoubleTap extends React.Component<Props> {
_timer: TimeoutID;
_previousPressEvent: ?PressEvent;
onPress = (event: PressEvent) => {
if (this._previousPressEvent) {
this.onReceiveSecondEvent(event);
} else {
this.onReceiveFirstEvent(event);
}
};
onReceiveFirstEvent = (event: PressEvent) => {
this._timer = setTimeout(() => {
this.props.onSingleTap(event);
this._previousPressEvent = null;
}, MAX_DOUBLE_TOUCH_DELAY_TIME);
this._previousPressEvent = event;
};
onReceiveSecondEvent = (event: PressEvent) => {
if (this._isDoubleTap(event)) {
this.props.onDoubleTap(event);
} else {
this.props.onSingleTap(event);
}
this._timer && clearTimeout(this._timer);
this._previousPressEvent = null;
};
_distanceBetweenTouches = (
touch1: PressEvent,
touch2: PressEvent
): number => {
const disX = touch1.nativeEvent.locationX - touch2.nativeEvent.locationX;
const disY = touch1.nativeEvent.locationY - touch2.nativeEvent.locationY;
return Math.sqrt(Math.pow(disX, 2) + Math.pow(disY, 2));
};
_isDoubleTap = (currentEvent: PressEvent) => {
if (!this._previousPressEvent) {
return false;
}
const distance = this._distanceBetweenTouches(
currentEvent,
this._previousPressEvent
);
// $FlowFixMe
const { nativeEvent } = this._previousPressEvent;
const delay = currentEvent.nativeEvent.timestamp - nativeEvent.timestamp;
return (
distance < MAX_DOUBLE_TOUCH_DISTANCE &&
delay < MAX_DOUBLE_TOUCH_DELAY_TIME
);
};
componentWillUnmount = () => {
this._timer && clearTimeout(this._timer);
};
render() {
return (
<TouchableOpacity onPress={this.onPress}>
{this.props.children}
</TouchableOpacity>
);
}
}
export default SingleDoubleTap;
如何使用?
<SingleDoubleTap
onSingleTap={this._onSingleTap}
onDoubleTap={this._onDoubleTap}>
..... // other components
</SingleDoubleTap>
关键是你应该等待 DoubleTap
事件未能将触摸事件识别为 OneTap
。
Hi, Thanks in advance, am using the Double click Component and it works well for double click event. But I need to get an action when user perform a single click. What the work around for this issue.
<DoubleClick onClick={(e) => this.hClick(value,e)}>
<View>
<Text>
{value.item}
</Text>
</View>
</DoubleClick>
取消双击,使用可触摸组件。将点击传递给函数,并使用定时器延迟
来判断是单击还是双击我写了一个组件。
// @flow
import * as React from 'react';
import { TouchableOpacity } from 'react-native';
import type { PressEvent } from 'react-native/Libraries/Types/CoreEventTypes';
type Props = {
children?: any,
onSingleTap: (event: PressEvent) => void,
onDoubleTap: (event: PressEvent) => void,
};
const MAX_DOUBLE_TOUCH_DISTANCE = 20;
const MAX_DOUBLE_TOUCH_DELAY_TIME = 250;
class SingleDoubleTap extends React.Component<Props> {
_timer: TimeoutID;
_previousPressEvent: ?PressEvent;
onPress = (event: PressEvent) => {
if (this._previousPressEvent) {
this.onReceiveSecondEvent(event);
} else {
this.onReceiveFirstEvent(event);
}
};
onReceiveFirstEvent = (event: PressEvent) => {
this._timer = setTimeout(() => {
this.props.onSingleTap(event);
this._previousPressEvent = null;
}, MAX_DOUBLE_TOUCH_DELAY_TIME);
this._previousPressEvent = event;
};
onReceiveSecondEvent = (event: PressEvent) => {
if (this._isDoubleTap(event)) {
this.props.onDoubleTap(event);
} else {
this.props.onSingleTap(event);
}
this._timer && clearTimeout(this._timer);
this._previousPressEvent = null;
};
_distanceBetweenTouches = (
touch1: PressEvent,
touch2: PressEvent
): number => {
const disX = touch1.nativeEvent.locationX - touch2.nativeEvent.locationX;
const disY = touch1.nativeEvent.locationY - touch2.nativeEvent.locationY;
return Math.sqrt(Math.pow(disX, 2) + Math.pow(disY, 2));
};
_isDoubleTap = (currentEvent: PressEvent) => {
if (!this._previousPressEvent) {
return false;
}
const distance = this._distanceBetweenTouches(
currentEvent,
this._previousPressEvent
);
// $FlowFixMe
const { nativeEvent } = this._previousPressEvent;
const delay = currentEvent.nativeEvent.timestamp - nativeEvent.timestamp;
return (
distance < MAX_DOUBLE_TOUCH_DISTANCE &&
delay < MAX_DOUBLE_TOUCH_DELAY_TIME
);
};
componentWillUnmount = () => {
this._timer && clearTimeout(this._timer);
};
render() {
return (
<TouchableOpacity onPress={this.onPress}>
{this.props.children}
</TouchableOpacity>
);
}
}
export default SingleDoubleTap;
如何使用?
<SingleDoubleTap
onSingleTap={this._onSingleTap}
onDoubleTap={this._onDoubleTap}>
..... // other components
</SingleDoubleTap>
关键是你应该等待 DoubleTap
事件未能将触摸事件识别为 OneTap
。