美文网首页
PanResponder的使用总结

PanResponder的使用总结

作者: 石小泉 | 来源:发表于2018-04-01 09:55 被阅读1063次

    简介

    对于简单的 touch 事件,React Native有4个专门的 touch 组件进行处理

    • TouchableHighlight
    • TouchableNativeFeedback
    • TouchableOpacity
    • TouchableWithoutFeedback

    他们可以绑定4种不同的响应方法

    • onPress
    • onPressIn
    • onPressOut
    • onLonePress

    而对于手指滑动操作,利用上面的方法无法实现,这时就用到 gesture responder system

    在React Native中,响应手势的基本单位是responder,具体来说,就是最常见的View组件。任何的View组件,都是潜在的responder,如果某个View组件没有响应手势操作,那是因为它还没有被“开发”。

    将一个普通的View组件开发成为一个能响应手势操作的responder,非常简单,只需要按照React Native的gesture responder system的规范,在props上设置几个方法即可。具体如下:

    View.props.onStartShouldSetResponder
    View.props.onMoveShouldSetResponder
    View.props.onResponderGrant
    View.props.onResponderReject
    View.props.onResponderMove
    View.props.onResponderRelease
    View.props.onResponderTerminationRequest
    View.props.onResponderTerminate

    这个是系统级别的手势相应,处理起来相对复杂,最常见的是使用 PanResponder

    PanResponder

    PanResponder 是 React Native 实现的一套手势相应方法,与gesture responder system 比起来,PanResponder 方法的抽象成都更高,使用起来也更加方便

    使用方法很简单,只要View.props中设置相应的方法即可

    panResponder = PanResponder.create({
        onStartShouldSetPanResponder: (evt, gestureState) => true,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onPanResponderGrant: (evt, gestureState) => {
            console.log('evt', evt)    
            console.log('gestureState', gestureState)
        },
        onPanResponderMove: (evt, gestureState) => {
            console.log('evt', evt)    
            console.log('gestureState', gestureState)
        },
        onPanResponderRelease: (evt, gestureState) => {
            console.log('evt', evt)    
            console.log('gestureState', gestureState)
        },
    })
    render() {
        <View style={styles.container}
            {...this.panResponder.panHandlers}
        > 
        ...
        </View>
    }
    

    简单说明5个方法

    方法名 说明
    onStartShouldSetPanResponder 负责处理用户通过触摸来激活一个 responser,如果返回值为 true,则表示这个 View 能够响应触摸手势被激活
    onMoveShouldSetPanResponder 负责处理用户通过移动来激活一个 responser,如果返回值为 true,则表示这个 View 能够响应滑动手势被激活
    onPanResponderGrant 如果组件被 responser 激活,则调用该方法
    onPanResponderMove 用户滑动手指时,调用该方法
    onPanResponderRelease 用户手指离开屏幕时,调用该方法

    在5个方法中,我们能够使用的参数有2个,分别是 evt 和 gesture

    参数 说明
    evt 获取触摸的位置在被响应的 View 中的相对坐标,evt.nativeEvent.locationX 和 evt.nativeEvent.locationY(这个方法很实用)
    gesture dx/dy:手势进行到现在的横向/纵向相对位移
    vx/vy:此刻的横向/纵向速度
    numberActiveTouches:responder上的触摸的个数

    一个简单的拖拽 View 的例子

    panResponder = PanResponder.create({
          onStartShouldSetPanResponder: () => true,
          onMoveShouldSetPanResponder: ()=> true,
          onPanResponderGrant: ()=>{
            this._top = this.state.top
            this._left = this.state.left
            this.setState({bg: 'red'})
          },
          onPanResponderMove: (evt,gs)=>{
            console.log(gs.dx+' '+gs.dy)
            this.setState({
              top: this._top+gs.dy,
              left: this._left+gs.dx
            })
          },
          onPanResponderRelease: (evt,gs)=>{
            this.setState({
              bg: 'white',
              top: this._top+gs.dy,
              left: this._left+gs.dx
          })}
        })
    
    render() {
        return(
            <View
                {...this.panResponder.panHandlers}
                style={[styles.rect,{
                    "backgroundColor": this.state.bg,
                    "top": this.state.top,
                    "left": this.state.left
                }]}
            >
            ...
            </View>
        )
    }
    
    panResponser.gif

    本文结束,欢迎大家加群共同学习

    QQ群:672509442

    😊😊😊😊

    相关文章

      网友评论

          本文标题:PanResponder的使用总结

          本文链接:https://www.haomeiwen.com/subject/xxdocftx.html