PanResponder的使用总结

2018-04-01  本文已影响1063人  石小泉

简介

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

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

而对于手指滑动操作,利用上面的方法无法实现,这时就用到 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

😊😊😊😊
上一篇下一篇

猜你喜欢

热点阅读