Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React-Native触摸事件详解 #2

Open
xchunzhao opened this issue Jan 23, 2019 · 0 comments
Open

React-Native触摸事件详解 #2

xchunzhao opened this issue Jan 23, 2019 · 0 comments

Comments

@xchunzhao
Copy link
Owner

React Native 触摸事件处理详解

部分转自 https://www.race604.com/react-native-touch-event/

触控是移动设备的核心功能,也移动应用交互的基础,Android 和 iOS 各自都有完善的触摸事件处理机制。React Native(以下简称 RN)提供了一套统一的处理方式,能够方便的处理界面中组件的触摸事件、用户手势等。本文尝试介绍 RN 中触摸事件处理。

  • RN基本触摸组件

    RN 的组件除了Text,其他组件默认是不支持点击事件,也不能响应基本触摸事件,所以 RN 中提供了几个直接处理响应事件的组件,基本上能够满大部分的点击处理需求TouchableHighlight, TouchableNativeFeedback, TouchableOpacityTouchableWithoutFeedback。因为这几个组件的功能和使用方法基本类似,只是 Touch 的反馈效果不一样,所以一般我们用 Touchable** 代替。Touchable** 有如下几个回调方法:

    • onPressIn: 点击开始
    • onPressOut: 点击结束或者离开
    • onPress: 单击事件回调
    • onLongPress: 长按事件回调

    RN 中提供的触摸组件使用非常简单,可以参考 官方文档,这里也不做详细的介绍了。下面主要介绍用户触摸事件处理。

  • 组件触摸事件处理

    我们知道,RN 的组件默认不进行处理触摸事件。组件要处理触摸事件,首先要“申请”成为摸事件的响应者(Responder),完成事件处理以后,会释放响应者的角色。一个触摸事件处理周期,是从用户手指按下屏幕,到用户抬起手指抬起结束,这是用户的一次完整触摸操作。

    单个组件的单次操作交互处理的生命周期如下:

    7-1-responder-lifecycle

    我们来详细分析一下事件处理的生命周期,在整个事件处理的过程中,组件有可能处于两种身份中的一种,并且可以相互切换:非事件响应者和事件响应者。

  • 手势识别

    连续的触摸事件,可以组成一些更高级手势,例如我们最常见的滑动屏幕内容,双指缩放(Pinch)或者旋转图片都是通过手势识别完成的。

    因为有些手势是很常用的,RN 也提供了内置的手势识别库 PanResponder,它封装了上面的事件回调函数,对触摸事件数据进行加工,完成滑动手势识别,向我们提供更加高级有意义的接口,如下:

    // 是否在移动时申请成为响应者
    * onMoveShouldSetPanResponder: (e, gestureState) => bool
    // 是否在移动时劫持响应
    * onMoveShouldSetPanResponderCapture: (e, gestureState) => bool
    * onStartShouldSetPanResponder: (e, gestureState) => bool
    * onStartShouldSetPanResponderCapture: (e, gestureState) => bool
    * 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) => bool
    

    Tips: onShouldBlockNativeResponder 表示是否用 Native 平台的事件处理,默认是禁用的,全部使用 JS 中的事件处理,注意此函数目前只能在 Android 平台上使用。

    触摸事件参数

    • NativeEvent
    changedTouches - 在上一次事件之后,所有发生变化的触摸事件的数组集合(即上一次事件后,所有移动过的触摸点)
    identifier - 触摸点的ID
    locationX - 触摸点相对于父元素的横坐标
    locationY - 触摸点相对于父元素的纵坐标
    pageX - 触摸点相对于根元素的横坐标
    pageY - 触摸点相对于根元素的纵坐标
    target - 触摸点所在的元素ID
    timestamp - 触摸事件的时间戳,可用于移动速度的计算
    touches - 当前屏幕上的所有触摸点的集合
    
    • gestureState
    stateID - 触摸状态的ID。在屏幕上有至少一个触摸点的情况下,这个ID会一直有效。
    moveX - 最近一次移动时的屏幕横坐标
    moveY - 最近一次移动时的屏幕纵坐标
    x0 - 当响应器产生时的屏幕坐标
    y0 - 当响应器产生时的屏幕坐标
    dx - 从触摸操作开始时的累计横向路程
    dy - 从触摸操作开始时的累计纵向路程
    vx - 当前的横向移动速度
    vy - 当前的纵向移动速度
    numberActiveTouches - 当前在屏幕上的有效触摸点的数量
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant