[Fixed] React Native Android — PanResponder — gestures not working
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