在原生的开发中,如果要自定义一些控件,可能会用到touch的相关方法,而React Native也有一套touch机制,说白了就是用JS写了一套方法打通android和ios平台,这里简单讲解下React Native(RN)的touch机制,这里先不过多深入研究,先熟悉下流程,至于RN的touch分发机制之后再详细讲解.

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:另一个组件已经成为了新的响应者,所以当前手势将被取消。

下面以一个简单的例子跑下整个流程。

功能:可以拖拽的小球,当松开那一刻判断小球是属于屏幕左边还是屏幕右边,属于左边则让小球紧靠屏幕左边,如靠屏幕右侧,则让小球紧靠屏幕右侧。

首先要成为响应者:

//用户开始触摸屏幕的时候,是否愿意成为响应者;
onStartShouldSetPanResponder(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,
}
});
}
}
主要就是判断下释放的那一刻,所处的位置,若属于左侧则置left=0,为右侧则至left=Util.size.width-CIRCLE_SIZE;
一切准备就绪,最后看我们如何运用在组件上吧,非常的简单:

<View
{...this._panResponder.panHandlers}
style={[styles.circle,this.state.style]}/>
这三个点其实就是对象的扩展运算符,说白了就是把panHandlers对象里面所有的属性填充到View中。通过源码我们也可以知道View中其实定义了一系列相关的属性:
propTypes: {
。。。
。。。
onResponderGrant: PropTypes.func,
onResponderMove: PropTypes.func,
onResponderTerminationRequest: PropTypes.func,
onStartShouldSetResponder: PropTypes.func,
}

到这里就结束了,整体上还算不复杂,就几个回调函数记住了就可以了。

最后看下效果图吧:

github:react-native-float-menu
---------------------
作者:jj120522
来源:CSDN
原文:https://blog.csdn.net/jj120522/article/details/52181569
版权声明:本文为博主原创文章,转载请附上博文链接!

此外附上 官方示例组件:

https://github.com/facebook/react-native/blob/master/RNTester/js/PanResponderExample.js

RN中移动组件开发的更多相关文章

  1. RN中关于组件中属性的传递

    比如: 组件A想要给组件B中的组件C传递一个属性prop class A extends Component{ render(){ return( <B title = "这是一个标题 ...

  2. AngularJS进阶(三十一)AngularJS项目开发技巧之获取模态对话框中的组件ID

    AngularJS项目开发技巧之获取模态对话框中的组件ID 需求 出于项目开发需求,需要实现的业务逻辑是:药店端点击查看"已发货""已收货"订单详情时,模块弹出 ...

  3. java 组件开发中的日志记录问题

    今天帮别人写封装几个url 请求,打成jar 包,可以以java接口的方式提供给外部访问. 遇到两个问题: 1. 是否把依赖的jar包也 打入 我要生成的jar包中,如果你不打入,别人直接调用接口会报 ...

  4. Angular 项目开发中父子组件传参

    在项目开发中经常会遇到 组件之间传参的问题.今天总结下在使用angular的项目中父子组件传参的问题: 1.父组件向子组件传参: 然后在父组件中 然后在父组件的html中 然后就可以在子组件中使用了 ...

  5. spring注解开发:容器中注册组件方式

    1.包扫描+组件标注注解 使用到的注解如下,主要针对自己写的类 @Controller @Service @Repository @Component @ComponentScan 参考 spring ...

  6. 微信小程序之组件开发中的基础知识

    跟着视频开始小程序的项目的开发,视频中这个小程序已经上线了,可以很好的看着小程序的界面进行开发,昨天看了一下具体的需求,觉得真的细节好多啊,而且其中设计的组件的思想也是很好的,能够很好的实现代码的复用 ...

  7. RN中的常用组件-----图片

    1.RN中的常用组件-----图片 本地图片: <Image  source={require('../src/assets/x.jpg')}/> 本地图片可以无需指定尺寸(因为导入/打包 ...

  8. 【Spring注解开发】组件注册-使用@Configuration和@Bean给容器中注册组件

    写在前面 在之前的Spring版本中,我们只能通过写XML配置文件来定义我们的Bean,XML配置不仅繁琐,而且很容易出错,稍有不慎就会导致编写的应用程序各种报错,排查半天,发现是XML文件配置不对! ...

  9. 在Vue前端项目中,附件展示的自定义组件开发

    在Vue前端界面中,自定义组件很重要,也很方便,我们一般是把一些通用的界面模块进行拆分,创建自己的自定义组件,这样操作可以大大降低页面的代码量,以及提高功能模块的开发效率,本篇随笔继续介绍在Vue&a ...

随机推荐

  1. nginx:负载均衡实战(二) keepalived入门

    1.keepalived介绍 顾名思义,keepalived就是保持网络在线的,用来保证集群高可用HA的服务软件.主要防止出现单点故障(坏了一个点导致整个系统架构不可用) 2.详解keepalived ...

  2. Python Django 之 直接执行自定义SQL语句(一)

    一.执行自定义SQL方法 1.Executing custom SQL directly      直接执行自定义SQL,这种方式可以完全避免数据模型,而是直接执行原始的SQL语句. 2.Manage ...

  3. javascript进阶笔记(3)

    本篇文章我们来学习和讨论一下js中的闭包.闭包是纯函数式编程的一个特性,因为它们能够大大简化复杂的操作.在js中,闭包的重要性不言而喻! 简单的说,闭包(closure)是 一个函数在创建时 允许 该 ...

  4. socket-重叠模型(overlap)

    socket-重叠模型(overlap) 重叠模型的基本设计原理便是让应用程序使用一个重叠的数据结构,一次投递一个或多个Winsock I/O请求.针对那些提交的请求,在它们完成之后,应用程序可为它们 ...

  5. 网站如何实现 在qq中发自己链接时,便自动获取链接标题、图片和部分内容

    如何实现像这种效果?答案如下(要采用分享的形式,复制链接有可能会实现不了效果,至少我的测试是这样的) <head>标签内有QQ专有的标签可以控制要注意QQ的缓存机制,对同一个链接,修改后可 ...

  6. SharePoint REST API - 列表和列表项

    博客地址:http://blog.csdn.net/FoxDave 本篇主要讲述如何用SharePoint REST操作列表和列表项.阅读本篇时请先了解前面讲述的REST介绍和基本操作. 废话不多 ...

  7. <kafka><应用场景><Kafka VS Flume>

    前言 最近在搭一个离线Hadoop + 实时SparkStreaming的日志处理系统,然后发现基本上网上的这种系统都集成了kafka. 自己对kafka有一点点的认识,之前看过官网文档,用过一次,就 ...

  8. tensorflow-learning-where-what-how

    这么优秀的外国小哥哥... https://github.com/machinelearningmindset/TensorFlow-Course tensorboard使用:https://gith ...

  9. pycharm 永久解封

    第一步   c:\windows\system32\drivers\etc    命令行输入这个 第二步     把host文件复制到桌面 第三步   记事本打开host 第四步    在最下面添加  ...

  10. Android大作业 --音乐播放器

    1.项目成员(本次作业主要对上一次的音乐播放器进行完善) 韦家城 学号:1600802026 班级:161  博客:https://www.cnblogs.com/ln9969cc/ 邓乾尧 学号:1 ...