Differential Revision: D6261799 fbshipit-source-id: 269e151c5d136c1d508d9f2a060c0c670d0fe0f2
5.7 KiB
id | title | layout | category | permalink | next | previous |
---|---|---|---|---|---|---|
panresponder | PanResponder | docs | APIs | docs/panresponder.html | permissionsandroid | netinfo |
PanResponder
reconciles several touches into a single gesture. It makes
single-touch gestures resilient to extra touches, and can be used to
recognize simple multi-touch gestures.
By default, PanResponder
holds an InteractionManager
handle to block
long-running JS events from interrupting active gestures.
It provides a predictable wrapper of the responder handlers provided by the
gesture responder system.
For each handler, it provides a new gestureState
object alongside the
native event object:
onPanResponderMove: (event, gestureState) => {}
A native event is a synthetic touch event with the following form:
nativeEvent
changedTouches
- Array of all touch events that have changed since the last eventidentifier
- The ID of the touchlocationX
- The X position of the touch, relative to the elementlocationY
- The Y position of the touch, relative to the elementpageX
- The X position of the touch, relative to the root elementpageY
- The Y position of the touch, relative to the root elementtarget
- The node id of the element receiving the touch eventtimestamp
- A time identifier for the touch, useful for velocity calculationtouches
- Array of all current touches on the screen
A gestureState
object has the following:
stateID
- ID of the gestureState- persisted as long as there at least one touch on screenmoveX
- the latest screen coordinates of the recently-moved touchmoveY
- the latest screen coordinates of the recently-moved touchx0
- the screen coordinates of the responder granty0
- the screen coordinates of the responder grantdx
- accumulated distance of the gesture since the touch starteddy
- accumulated distance of the gesture since the touch startedvx
- current velocity of the gesturevy
- current velocity of the gesturenumberActiveTouches
- Number of touches currently on screen
Basic Usage
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} />
);
},
Working Example
To see it in action, try the PanResponder example in RNTester
Methods
Reference
Methods
create()
static create(config)
@param {object} config Enhanced versions of all of the responder callbacks
that provide not only the typical ResponderSyntheticEvent
, but also the
PanResponder
gesture state. Simply replace the word Responder
with
PanResponder
in each of the typical onResponder*
callbacks. For
example, the config
object would look like:
onMoveShouldSetPanResponder: (e, gestureState) => {...}
onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}
onStartShouldSetPanResponder: (e, gestureState) => {...}
onStartShouldSetPanResponderCapture: (e, gestureState) => {...}
onPanResponderReject: (e, gestureState) => {...}
onPanResponderGrant: (e, gestureState) => {...}
onPanResponderStart: (e, gestureState) => {...}
onPanResponderEnd: (e, gestureState) => {...}
onPanResponderRelease: (e, gestureState) => {...}
onPanResponderMove: (e, gestureState) => {...}
onPanResponderTerminate: (e, gestureState) => {...}
onPanResponderTerminationRequest: (e, gestureState) => {...}
onShouldBlockNativeResponder: (e, gestureState) => {...}
In general, for events that have capture equivalents, we update the gestureState once in the capture phase and can use it in the bubble phase as well.
Be careful with onStartShould* callbacks. They only reflect updated
gestureState
for start/end events that bubble/capture to the Node.
Once the node is the responder, you can rely on every start/end event
being processed by the gesture and gestureState
being updated
accordingly. (numberActiveTouches) may not be totally accurate unless you
are the responder.