探究react native的View
最近需要用到React-native的手势操作,从而去看了关于View的许多文档,现在做个总结。
首先,还是要知道他的解释,看了文档的都知道,react-native的View,不论在什么平台上,他都对应一个平台的原生视图,无论他是UIView、div、还是Android.view.View。
然后再是去看他的属性方法,这些属性方法就是今天的重头戏了。
一、onLayout function
当组件挂载或者变化的时候调用,内部有nativeEvent.layout属性,包含四个参数:
x(距离根元素x轴距离),
y(记录根元素y轴距离),
width(当前View的宽),
height(当前View的高),
例子:
<View style={{flex:1,}} onLayout={(event) => { var viewWidth = event.nativeEvent.layout.width; var viewHeight = event.nativeEvent.layout.height; if (!viewWidth || this.state.containerViewWidth === viewWidth) { return; } this.setState({ containerViewWidth: viewWidth, containerViewHeight: viewHeight, }); }}/>
以上例子把View的宽和高保存在state中,用于以后计算
二、手势操作
1.View.porps.handleStartShouldSetPanResponder
用户通过触摸激活手势的responder,返回true
2.View.porps.onMoveSetPanResponder
用户通过滑动激活手势的responder,返回true
3.View.porps.handlePanResponderGrant
如果组件被激活,该方法调用,一般用于显示激活的状态
4.View.porps.handlePanResponderReject
多个respond被触发时,触发该方法的不激活respond
5.View.porps.handlePanResponderMove
用户滑动手指,该方法被调用
6.View.porpshandlePanResponderEnd
用户释放手指,该方法被调用,一般用于恢复无激活时的状态
7.View.porps.handlePanRespondeTerminationRequest
多个respond被触发时,该方法决定谁被激活(一个组件只允许同时激活一个respond)
8.View.porps.onStartShouldSetResponderCapture
9.View.porps.onMoveShouldSetResponderCapture
组合技能:
1和2同时返回为true,表示respond被激活
8和9同时返回为true,表示同一家族(即祖宗、父、子组件)中该组件被激活。这个要多讲一下,因为组件的respond激活是按照冒泡排序的,即最内层(子组件)最先被激活。而当你在外层即父组件的8和9设置返回true时,该组件优先被激活。
所以一次正常的触摸手势流程为:
touch或move --> grant --> move --> release
以上方法被操作时还会传入两个值(e: Object, gestureState: Object)
e表示event
gestureState里面有三个参数:
dx/dy:手势进行到现在的横向/纵向相对位移
vx/vy:此刻的横向/纵向速度
numberActiveTouches:responder上的触摸的个数
例子如下:
_highlight: function() { this._circleStyles.style.backgroundColor = 'red'; this._updateNativeStyles(); }, _unHighlight: function() { this._circleStyles.style.backgroundColor = 'black'; this._updateNativeStyles(); }, _updateNativeStyles: function() { this.circle && this.circle.setNativeProps(this._circleStyles); }, _handleStartShouldSetPanResponder: function(e: Object, gestureState: Object): boolean { // Should we become active when the user presses down on the circle? return true; }, _handleMoveShouldSetPanResponder: function(e: Object, gestureState: Object): boolean { // Should we become active when the user moves a touch over the circle? return true; }, _handlePanResponderGrant: function(e: Object, gestureState: Object) { this._highlight(); }, _handlePanResponderMove: function(e: Object, gestureState: Object) { this._circleStyles.style.left = xxx; this._circleStyles.style.top = yyy; let rad = this.state.containerViewWidth - CIRCLE_SIZE this._circleStyles.style.left = this._previousLeft + gestureState.dx; this._circleStyles.style.top = this._previousTop + gestureState.dy; this._updateNativeStyles(); }, _handlePanResponderEnd: function(e: Object, gestureState: Object) { this._unHighlight(); this._previousLeft += gestureState.dx; this._previousTop += gestureState.dy; },
不激活时为黑色,点击时为红色,该组件随手势移动。
三、style
在View的style里面有个一个transform属性,前端的童鞋应该都知道吧
transform [{perspective: number}, {rotate: string}, {rotateX: string}, {rotateY: string}, {rotateZ: string}, {scale: number}, {scaleX: number},
{scaleY: number}, {translateX: number}, {translateY: number}, {skewX: string}, {skewY: string}]
用它愉快的去玩耍吧
例子:
<View style={{width: 100, height: 100, backgroundColor:'red', transform: [ {scale: 2}, {rotateZ: '7deg',} ]}}/>