在 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