Skip to main content

PanResponder

PanResponder 将多个触摸整合为一个手势。它使单点触摸手势能够适应额外的触摸,并且可用于识别基本的多点触摸手势。

¥PanResponder reconciles several touches into a single gesture. It makes single-touch gestures resilient to extra touches, and can be used to recognize basic multi-touch gestures.

默认情况下,PanResponder 持有 InteractionManager 句柄,以阻止长时间运行的 JS 事件中断活动手势。

¥By default, PanResponder holds an InteractionManager handle to block long-running JS events from interrupting active gestures.

它提供了 手势响应系统 提供的响应程序处理程序的可预测封装。对于每个处理程序,它在原生事件对象旁边提供一个新的 gestureState 对象:

¥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) => {}

原生事件是形式为 PressEvent 的合成触摸事件。

¥A native event is a synthetic touch event with form of PressEvent.

gestureState 对象具有以下内容:

¥A gestureState object has the following:

  • stateID - 手势状态的 ID - 只要屏幕上至少有一次触摸就会持续存在

    ¥stateID - ID of the gestureState- persisted as long as there's at least one touch on screen

  • moveX - 最近移动触摸的最新屏幕坐标

    ¥moveX - the latest screen coordinates of the recently-moved touch

  • moveY - 最近移动触摸的最新屏幕坐标

    ¥moveY - the latest screen coordinates of the recently-moved touch

  • x0 - 响应者授予的屏幕坐标

    ¥x0 - the screen coordinates of the responder grant

  • y0 - 响应者授予的屏幕坐标

    ¥y0 - the screen coordinates of the responder grant

  • dx - 自触摸开始以来手势的累计距离

    ¥dx - accumulated distance of the gesture since the touch started

  • dy - 自触摸开始以来手势的累计距离

    ¥dy - accumulated distance of the gesture since the touch started

  • vx - 手势的当前速度

    ¥vx - current velocity of the gesture

  • vy - 手势的当前速度

    ¥vy - current velocity of the gesture

  • numberActiveTouches - 当前屏幕上的触摸次数

    ¥numberActiveTouches - Number of touches currently on screen

使用模式

¥Usage Pattern

const ExampleComponent = () => {
const panResponder = React.useRef(
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;
},
}),
).current;

return <View {...panResponder.panHandlers} />;
};

示例

¥Example

PanResponderAnimated API 配合使用,帮助在 UI 中构建复杂的手势。以下示例包含一个动画 View 组件,可以在屏幕上自由拖动

¥PanResponder works with Animated API to help build complex gestures in the UI. The following example contains an animated View component which can be dragged freely across the screen

试试 RNTester 中的 PanResponder 示例

¥Try the PanResponder example in RNTester.


参考

¥Reference

方法

¥Methods

create()

static create(config: PanResponderCallbacks): PanResponderInstance;

参数:

¥Parameters:

名称类型描述
配置
必填
object参考下文

config 对象提供了所有响应者回调的增强版本,通过在每个典型 onResponder* 回调中将单词 Responder 替换为 PanResponder,不仅提供 PressEvent,还提供 PanResponder 手势状态。例如,config 对象如下所示:

¥The config object provides enhanced versions of all of the responder callbacks that provide not only the PressEvent, but also the PanResponder gesture state, by replacing 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) => {...}

一般来说,对于具有捕获等效项的事件,我们在捕获阶段更新一次 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.

小心 onStartShould* 回调。它们仅反映更新的 gestureState 用于冒泡/捕获到节点的开始/结束事件。一旦节点成为响应者,你就可以依赖手势处理的每个开始/结束事件以及相应更新的 gestureState。除非你是响应者,否则 (numberActiveTouches) 可能不完全准确。

¥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.