You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
changedTouches - Array of all touch events that have changed since the last event
identifier - The ID of the touch
locationX - The X position of the touch, relative to the element
locationY - The Y position of the touch, relative to the element
pageX - The X position of the touch, relative to the screen
pageY - The Y position of the touch, relative to the screen
target - The node id of the element receiving the touch event
timestamp - A time identifier for the touch, useful for velocity calculation
touches - Array of all current touches on the screen
习惯了前端世界的交互模式之后(其实就是 DOM 事件),在这个入门的过程中感觉 React Native 的交互处理就是个不适应。
如果要做 React Native 的交互,首先至少要知道这样几个东西:
不过干读这几个文档的话,基本就是一头雾水……
还是一点一点来看罢:
普通行为
TouchableHighlight、TouchableOpacity、TouchableWithoutFeedback 这几个很好弄,官方贴心的直接封装了最基础的 Touch 行为,在任何需要点击的 View 外面直接包上这样的标签就行了。
TouchableHighlight 在点击时表现为高亮
TouchableOpacity 在点击时表现为透明
TouchableWithoutFeedback 在点击时无反馈
这几个效果都是封装好了的,无需开发者操心。
Sample Code
然而这些只适用于按钮系……
支持事件:
支持参数:
再特殊点的行为,例如划过,就不用想用这几个货直接实现了。
Gesture Responder System
中文翻译叫:手势应答系统。
主要就是搞手势识别处理的,那其实也就是复杂点的触摸:例如一边摸一遍动啊,摸着还动出花样画个 L 啥的的那种。
事件
决定是否成为处理器
冒泡的:
touchStart
/mouseDown
行为发生,是否当前的元素成为处理器touchMove
/mouseMove
行为发生,是否当前行为成为处理器不冒泡/未来不冒泡的:
是否接管成为处理器(因为冒泡是从最深处开始,可以在父级的元素使用此类方法接管):
touchStart
/mouseDown
行为发生,是否当前的元素代替最深层的子元素成为处理器touchStart
/mouseDown
行为发生,是否当前的元素代替最深层的子元素成为处理器开始处理了
touchUp
跟拦截相关的(当前应答器的身份)
行为生命周期
这个图画的我头晕啊……
几个特性
冒泡
之前说到,有两个东西是冒泡的:
然则默认是触发最深的那个元素,也就是子级元素,如果父级要拦截作为处理器,则需要处理:
这两个事件的触发顺序是从父级开始的,所以如果父级设置了返回 true,则会执行父级的处理。
但是如果任一返回了 false,则依然使用子级元素作为处理器。
不过如果父级的
onStartShouldSetResponder
如果返回 false,干脆不会触发父级的验证,onStartShouldSetResponderCapture
返回 true 也没用,Move 也是同理。拦截
话说这个还没搞明白怎么用……
简单用法
直接写属性,作为 prop:
也可以使用...运算符:
也可以使用
PanResponder
(这个会在实际处理的事件前加个 Pan,输出时又会去掉,而且会增加一个参数gestureState
):特殊行为
划走切换的效果
可以参考:http://www.terlici.com/2015/04/06/simle-slide-menu-react-native.html
就是使用 PanResponder + Animation做的。
这个回头我自己再搞个出来。
手势解锁
因为不想用 WebView 做,所以这里都是从纯 React Native 的角度去考虑的。
因为生命周期中,TouchIn 是起点,所以如果在外面按住了划过元素,元素是不会有反应的……
单纯的子级接管作为处理器然后释放也是没用的,如果同时设置 Capture,父级的优先级大……
那么是否可以这样呢?父级判断碰撞,然后释放处理权?但是拦截的判断只在最开始触发的时候能搞,所以似乎还是行不通的。而且都碰撞到了,如果能直接处理子元素不是更简便么?
没那么简单,需要看看这三个方法:
子元素的获取
使用 refs:
这样就可以直接通过
this.refs[name]
获取到子元素了。获取子元素的位置
这是从 React Native 的 Issue 1374 拿到的方法:
所以,元素在屏幕中的范围是:pageX ~ pageX + width, pageY ~ pageY + height
至少是个简单的正方形,如果是其他形状例如圆形,可能还需要计算圆心和半径的大小。
获取当前 touch 的坐标
之前说过 PanResponder 会给事件方法增加一个参数
gestureState
:一个 gestureState 对象有以下属性:
那么 touch 位置的坐标可以这么获得:[x0 + dx, y0 + dy]
当然也可以使用都有的 evt 参数:
changedTouches - Array of all touch events that have changed since the last event
identifier - The ID of the touch
locationX - The X position of the touch, relative to the element
locationY - The Y position of the touch, relative to the element
pageX - The X position of the touch, relative to the screen
pageY - The Y position of the touch, relative to the screen
target - The node id of the element receiving the touch event
timestamp - A time identifier for the touch, useful for velocity calculation
touches - Array of all current touches on the screen
直接用[pageX, pageY] 就行了。
这样就可以进行简单的碰撞计算了,计算位置是否在某个子元素的范围内就行了。
实际上至此手势解锁的几个关键问题已经解决,正在写一个手势解锁的组件:k-react-native-swipe-unlock 玩耍。
To Be Continued.
The text was updated successfully, but these errors were encountered: