android – Use double click and single click simultaneously in react native-ThrowExceptions

Exception or error:

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>
How to solve:

I wrote a component.


// @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;

How to use it?

<SingleDoubleTap
   onSingleTap={this._onSingleTap}
   onDoubleTap={this._onDoubleTap}> 
  ..... // other components
</SingleDoubleTap> 

The key thing is you should wait for the DoubleTap event failed to recognize the touch event as OneTap.

###

Remove the double click and use touchable component. pass the click to function and find whether its single or double click using timer delay

Leave a Reply

Your email address will not be published. Required fields are marked *