Farooq Karimi Zadeh
Farooq Karimi Zadeh

Reputation: 79

How to detect simultaneous touches in React Native on Android?

I'm developing an app which requires handling of simultaneous touches(usually 2 or 3 at most). So that the user can have multiple buttons pressed at the same time. The problem's that on Android when the user presses one of the buttons(not necessary RN's <Button>), they cannot press the others as long as the first button is hold. First I had tried RN's <Pressable>, to receive both PressIn and PressOut events, in a way like this:


const Key = ({label, ...}): Node => {
  const [hold, setHold] = useState(false);
  return (
    <Pressable
      onPressIn={...}
      onPressOut={...}
      style={hold ? styles.keyHold : styles.keyUnhold}
    >
      <Text>{label}</Text>
    </Pressable>
  );
};


const Keyboard = ({...}): Node => {
  //...
  return (
    <FlatList
      data={data}
      renderItem={({item}) => {
        const {label, name} = item;
        return <Key title={label} ... />;
      }}
    />
  );
};

And it had the said problem. Afterwards I had found many answers on StackOverflow(React Native - onTouchStart vs PanResponder for multiple touches per second How do I enable touch on multiple buttons simultaneously in react native? How to detect simultaneous onPress events in react native?) and I tried onTouchStart/onTouchEnd and <View> replacing <Pressable> and onPressIn/onPressOut. The problem remains except that when holding a button(constructed using <View>) and trying to press another one, the first one is released and any touch on the screen will trigger the first one(which is still physically hold).

Many answers and comments on the posted questions suggest using PanResponder but by ducking I cannot find any example of achieving something like what I want using PanResponder.

So the question is that: How to achieve this in RN? Should I use PanResponder? If yes, an example on how to do that can really be helpful for me. Or perhaps there are other ways of achieving this of which I'm unaware?

(I'm using RN 0.66 on a real Android device running 7.1)

Upvotes: 0

Views: 775

Answers (2)

Tushar Shahi
Tushar Shahi

Reputation: 20676

This is now very much possible using GestureDetector:

You can use onBegin

const MutliTapAllowButton = ({ children, callback }) => {
    const tap = Gesture.Tap()
    /*.runOnJS(true)*/ should work without this too
    .onBegin(callback)

    return <GestureDetector gesture={tap}>{children}</GestureDetector>
}

This should be rendered inside GestureHandlerRootView

Upvotes: 0

Yaroslav Pesotskii
Yaroslav Pesotskii

Reputation: 91

This dont work whit element Pressable or Touchable instead of this you can use element View with event onTouchStart and onTouchEnd

  <View>
               <View onTouchStart={onPressInFirst} onTouchEnd={onPressOutFirst}>
                  <Text>BUTTON 1</Text>
                </View>
                <View onTouchStart={onPressInSecond} onTouchEnd={onPressOutSecond}>
                  <Text>BUTTON 2</Text>
                </View>
</View>

Upvotes: 0

Related Questions