本站文章均为李华明Himi原创,转载务必在明显处注明:@H_404_5@转载自【黑米GameDev街区】 原文链接:http://www.himigame.com/react-native/2203.html@H_404_5@@H_404_5@
本文是RN(React Native)系列教程第一篇,当然也要给自己的群做个广告:
React Native @Himi :126100395 刚创建的群,欢迎一起学习、讨论、进步。
本文主要讲解两点:
1. PanResponder:触摸事件,用以获取用户手指所在屏幕的坐标(x,y)或触发、或滑动、或抬起几种事件通知。
2. Touchable:React为我们封装好的触摸组件。引用原文:“响应系统用起来可能比较复杂。所以我们提供了一个抽象的Touchable
实现,用来做“可触控”的组件。这一实现利用了响应系统,使得你可以简单地以声明的方式来配置触控处理。”
一:触摸事件各事件响应与坐标获取
1. 在import React 中添加要使用的触摸组件:
importReact,{ ... PanResponder,//触摸必要的组件 ... }from'react-native';
2. 声明:
constructor(props){ super(props); this.state={ eventName:'',pos:'',}; this.myPanResponder={} }
这里先声明了两个变量posX,posY用于显示坐标用,另外声明了一个myPanResponder 用于后面的触摸事件。
3. 创建、设置与响应
componentWillMount(){ this.myPanResponder=PanResponder.create({ //要求成为响应者: onStartShouldSetPanResponder:(evt,gestureState)=>true,onStartShouldSetPanResponderCapture:(evt,onMoveShouldSetPanResponder:(evt,onMoveShouldSetPanResponderCapture:(evt,onPanResponderTerminationRequest:(evt,//响应对应事件后的处理: onPanResponderGrant:(evt,gestureState)=>{ this.state.eventName='触摸开始'; this.forceUpdate(); },onPanResponderMove:(evt,gestureState)=>{ var_pos='x:'+gestureState.moveX+',y:'+gestureState.moveY; this.setState({eventName:'移动',pos:_pos}); },onPanResponderRelease:(evt,gestureState)=>{ this.setState({eventName:'抬手'}); },onPanResponderTerminate:(evt,gestureState)=>{ this.setState({eventName:'另一个组件已经成为了新的响应者'}) },}); }
以上代码分为3部分,先创建,然后对需要追踪的事件进行设置响应,最后重写响应的事件进行处理即可。
需要注意的:绑定到componentDidMount的话可能会失效,需要在componentWillMount处预先创建手势响应器
4. 为要响应的View进行设置
1 |
{..thismyPanResponderpanHandlers} |
5. 完善Render函数:
render(){ return( <Viewstyle={styles.himiViewStyle} {...this.myPanResponder.panHandlers} > <Textstyle={styles.himiTextStyle}>HimiReactNative教程</Text> <Viewstyle={styles.container}> <Textstyle={styles.text}>{this.state.eventName}</Text> <Textstyle={styles.text}>{this.state.pos}</Text> </View> </View> )}
6.用到的布局和样式:
varstyles=StyleSheet.create({ container:{ flex:1,flexDirection:'row',justifyContent:'center',alignItems:'center',backgroundColor:'#F5FCFF',},text:{ color:'#f00',fontSize:30,himiViewStyle:{ flex:1,flexDirection:'column',himiTextStyle:{ color:'#f00',marginTop:70,});
如上是第一种形式,下面我们简单说下如何使用第二种形式:
componentWillMount(){ this.myPanResponder=PanResponder.create({ //*********************第二种触摸的形式*************************** //类似shouldComponentUpdate,监听手势开始按下的事件,返回一个boolean决定是否启用当前手势响应器 onStartShouldSetPanResponder:this._handleStartShouldSetPanResponder.bind(this),//监听手势移动的事件,返回一个boolean决定是否启用当前手势响应器 onMoveShouldSetPanResponder:this._handleMoveShouldSetPanResponder.bind(this),//手势开始处理 onPanResponderGrant:this._handlePanResponderGrant.bind(this),//手势移动时的处理 onPanResponderMove:this._handlePanResponderMove.bind(this),//用户放开所有触点时的处理 onPanResponderRelease:this._handlePanResponderRelease.bind(this),//另一个组件成了手势响应器时(当前组件手势结束)的处理 onPanResponderTerminate:this._handlePanResponderEnd.bind(this) }); } _handleStartShouldSetPanResponder(e,gestureState){ //返回一个boolean决定是否启用当前手势响应器 returntrue; } _handleMoveShouldSetPanResponder(e,gestureState){ returntrue; } _handlePanResponderGrant(e,gestureState){ this.setState({ eventName:'Start' }) } _handlePanResponderRelease(e,gestureState){ this.setState({ eventName:'End' }) } _handlePanResponderMove(e,gestureState){ var_pos='x:'+gestureState.moveX+',y:'+gestureState.moveY; this.setState({ eventName:'Move:',pos:_pos }) } _handlePanResponderEnd(e,gestureState){ this.setState({ eventName:'另一个组件成了手势响应器时(当前组件触摸结束)的处理' }) }
第二种形式就是将触摸响应绑定到我们自定义的函数,其他没有基本没区别。改动只有两点:
二:四种 Touchable 触摸组件
Touchable 一共有四种形式:
TouchableHighlight: 当按下的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。
TouchableNativeFeedback:(仅限Android平台)在Android设备上,这个组件利用原生状态来渲染触摸的反馈。
TouchableOpacity: 当按下的时候,封装的视图的不透明度会降低。这个过程并不会真正改变视图层级,大部分情况下很容易添加到应用中而不会带来一些奇怪的副作用。
TouchableWithoutFeedback: 除非你有一个很好的理由,否则不要用这个组件。所有能够响应触屏操作的元素在触屏后都应该有一个视觉上的反馈(然而本组件没有任何视觉反馈),仍会触发触摸事件的响应
1. 添加Touchable的四种组件
importReact,{ ... Image,Alert,TouchableHighlight,TouchableNativeFeedback,TouchableOpacity,TouchableWithoutFeedback,... }from'react-native';
Himi这里还添加了Image和Alert两个组件:
Image 是图片组件,这里是为了测试效果,将Touchable发生在图片
Alert 弹窗提示组件,是为了通过弹窗,更好的展示出事件响应效果
2. 在Render添加如下:
<Viewstyle={styles.container}> <TouchableHighlight underlayColor='#4169e1' onPress={this.test} > <Image source={require('./res/himi.png')} style={{width:70,height:70}} /> </TouchableHighlight> <TouchableOpacity activeOpacity={0.5} onPress={()=>{Alert.alert('Himi','TouchableOpacity');}} > <Image source={require('./res/himi.png')} style={{width:70,height:70}} /> </TouchableOpacity> <TouchableWithoutFeedback underlayColor='#4169e1' activeOpacity={0.5} onPress={()=>{Alert.alert('Himi','TouchableWithoutFeedback');}} > <Image source={require('./res/himi.png')} style={{width:70,height:70}} /> </TouchableWithoutFeedback> </View>
由于Himi写博客时在Mac下,那么如下我们来创建除仅限Android的TouchableNativeFeedback之外的三种形式。
根据反馈的形式,大家可以自行设置其透明度、背景色、样式等。
效果图如下:(点击查看动态图)
注意:Touchable 组件系列都只能包含一个子组件,也就是说你想多个,可以嵌套View组件来实现。如:
<TouchableHighlight> <View> <Text>t1</Text> <Text>t2</Text> </View> </TouchableHighlight>