Codementor Events

[Fixed] React Native Android — PanResponder — gestures not working

Published Jan 22, 2019

In my case, I followed the official RN docs for pan-responder. It responded on iOS but not any android phone I tested on.

RN docs suggests you use the following:

componentWillMount: function() {
    this._panResponder = PanResponder.create({
        // Ask to be the responder:
        onStartShouldSetPanResponder: (evt, gestureState) => true,
        onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,

        onPanResponderGrant: (evt, gestureState) => {
            // The gesture has started. Show visual feedback so the user knows
            // what is happening!

            // gestureState.d{x,y} will be set to zero now
        },
        onPanResponderMove: (evt, gestureState) => {
            // The most recent move distance is gestureState.move{X,Y}

            // The accumulated gesture distance since becoming responder is
            // gestureState.d{x,y}
        },
        onPanResponderTerminationRequest: (evt, gestureState) => true,
        onPanResponderRelease: (evt, gestureState) => {
            // The user has released all touches while this view is the
            // responder. This typically means a gesture has succeeded
        },
        onPanResponderTerminate: (evt, gestureState) => {
            // Another component has become the responder, so this gesture
            // should be cancelled
        },
        onShouldBlockNativeResponder: (evt, gestureState) => {
            // Returns whether this component should block native components from becoming the JS
            // responder. Returns true by default. Is currently only supported on android.
            return true;
        },
    });
},

render: function() {
    return (
        <View {...this._panResponder.panHandlers} />
    );
},

After playing around with it, it works on Android by modifying the same block to

// Ask to be the responder:
onStartShouldSetPanResponder: (evt, gestureState) => {
    return false;
},
onStartShouldSetPanResponderCapture: (evt, gestureState) => {
    return false;
},

onMoveShouldSetPanResponder: (evt, gestureState) => {
    // Listen for your events and show UI feedback here
    return false;
},
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
    return false;
},
onPanResponderGrant: (evt, gestureState) => {
   return false;
},
onPanResponderMove: (evt, gestureState) => {
    return false;
},
onPanResponderTerminationRequest: (evt, gestureState) => {
    return false
},
onPanResponderRelease: (evt, gestureState) => {
    // This wont get called
    return true;
},
onPanResponderTerminate: (evt, gestureState) => {
    return false;
},
onShouldBlockNativeResponder: (evt, gestureState) => {
   return false;
},

The difference here is to return false on the “onStartShouldSetPanResponder”, “onStartShouldSetPanResponderCapture” and “onMoveShouldSetPanResponderCapture” events, then place your logic in the “onMoveShouldSetPanResponder” instead of the “onPanResponderRelease” event.

Hope it helps someone. Cheers

Discover and read more posts from Daniel Oduonye
get started
post commentsBe the first to share your opinion
Show more replies