一、概念
在原生的开发中,如果要自定义一些控件,可能会用到touch相关方法,而React Native也有一套touch机制,说白了就是用JS写了一套方法打通android和ios平台。
PanResponder:可以将多点触摸操作协调成一个手势。它使得一个单点触摸可以接受更多的触摸操作,也可以用于识别简单的多点触摸手势。
二、创建
创建部分代码:
componentWillMount(evt, gestureState){
this._panResponder=PanResponder.create({
onStartShouldSetPanResponder:this.onStartShouldSetPanResponder,
onMoveShouldSetPanResponder:this.onMoveShouldSetPanResponder,
onPanResponderGrant:this.onPanResponderGrant,
onPanResponderMove:this.onPanResponderMove,
onPanResponderRelease:this.onPanResponderEnd,
onPanResponderTerminate:this.onPanResponderEnd,
});
}
onStartShouldSetPanResponder
用户开始触摸屏幕的时候,是否愿意成为响应者,默认返回false,当返回true的时候则可以进行之后的事件传递。
onMoveShouldSetPanResponder
在每一个触摸点开始移动的时候,再询问一次是否响应触摸交互;
onPanResponderGrant
开始手势操作,也就是说按下去给用户一些视觉反馈(如可以改变颜色)。
onPanResponderMove
最近一次的移动距离.如:(获取x轴y轴方向的移动距离 gestureState.dx,gestureState.dy)。
onPanResponderRelease:
用户放开所有触点,且此时视图已经成为了响应者。
onPanResponderTerminate
另一个组件已经成为了新的响应者,所以当前手势江北取消。
三、实例
功能:可以拖拽的小球,当松开小球的那一刻判断小球是属于屏幕左边还是屏幕右边,属于左边则让小球紧靠屏幕左边,如靠右,则让小球紧靠屏幕右侧。
首先要成为响应者
/* 用户开始触摸屏幕的时候,是否愿意成为响应者 */
onStartShouldSetPanResponders(evt, gestureState){
return true;
}
/* 在每一个触摸点开始移动的时候,再次询问依次是否响应触摸交互 */
onMoveShouldSetPanResponder(evt, gestureState){
return true;
}
如果我们要修改点击小球后的颜色可以在onPanResponderGrant方法中处理
/* 开始收拾操作,给用户一些视觉反馈 */
onPanResponderGrant(evt, gestureState){
console.log('onPanResponderGrant...');
this.setState({
style:{
backgroundColor:'red',
left:_previousLeft,
top:_previousTop,
}
});
}
_previousLeft和_previousTop是两个变量,用来记录小球移动坐标
接下来看onPanResponderMove方法
// 最近一次的移动距离为
gestureState.move{X,Y}
onPanResponderMove(evt, gestureState){
_previousLeft=lastLeft+gestureState.dx;
_previousTop=lastTop+gestureState.dy;
if(_previousLeft<=0){
_previousLeft=0;
}
if(_previousTop<=0){
_previousTop=0;
}
if(_previousLeft>=Util.size.width-CIRCLE_SIZE){
_previousLeft=Util.size.width-CIRCLE_SIZE;
}
if(_previousTop>=Util.size.height-CIRCLE_SIZE){
_previousTop=Util.size.height-CIRCLE_SIZE;
}
//实时更新
this.setState({
style:{
backgroundColor:'red',
left:_previousLeft,
top:_previousTop,
}
});
}
当用户松开的onPanResponderRelease回调方法
/* 用户放开了所有的触摸点且此时视图已经成为了响应者
一般来说这意味着一个手势操作已经成功完成。 */
onPanResponderEnd(evt, gestureState){
lastLeft=_previousLeft;
lastTop=_previousTop;
this.changePosition();
}
/* 根据位置做出相应的处理 */
changePosition(){
if(_previousLeft+CIRCLE_SIZE/2 <= Util.size.width/2){
_previousLeft=lastLeft=0;
this.setState({
style:{
left:_previousLeft,
top:_previousTop,
}
});
}else{
_previousLeft=lastLeft=Util.size.width-CIRCLE_SIZE;
this.setState({
style:{
left:_previousLeft,
top:_previousTop,
}
});
}
}
运行组件
<View
{...this._panResponder.panHandlers}
style={[styles.circle,this.state.style]}/>
三个点就是对象的扩展运算符,说白了就是把panHandlers对象里面所有的属性填充到View中