博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【REACT NATIVE 系列教程之一】触摸事件的两种形式与四种TOUCHABLE组件详解
阅读量:5823 次
发布时间:2019-06-18

本文共 6004 字,大约阅读时间需要 20 分钟。

本文是RN(React Native)系列教程第一篇,当然也要给自己的群做个广告:

  React Native @Himi :126100395  刚创建的群,欢迎一起学习、讨论、进步。

本文主要讲解两点:

1.   PanResponder:触摸事件,用以获取用户手指所在屏幕的坐标(x,y)或触发、或滑动、或抬起几种事件通知。

2.   Touchable:React为我们封装好的触摸组件。引用原文:“响应系统用起来可能比较复杂。所以我们提供了一个抽象的Touchable实现,用来做“可触控”的组件。这一实现利用了响应系统,使得你可以简单地以声明的方式来配置触控处理。”

    一:触摸事件各事件响应与坐标获取

1. 在import React 中添加要使用的触摸组件:

1
2
3
4
5
import React, {
  
...
  
PanResponder,
//触摸必要的组件
  
...
} from 
'react-native'
;

2. 声明:

1
2
3
4
5
6
7
8
constructor(props) {
 
super
(props);
 
this
.state = {
               
eventName:
''
,
        
pos: 
''
,
 
};
    
this
.myPanResponder={}
}


这里先声明了两个变量posX,posY用于显示坐标用,另外声明了一个 myPanResponder 用于后面的触摸事件。

 

3. 创建、设置与响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
componentWillMount() {
      
this
.myPanResponder = PanResponder.create({
      
//要求成为响应者:
      
onStartShouldSetPanResponder: (evt, gestureState) => 
true
,
      
onStartShouldSetPanResponderCapture: (evt, gestureState) => 
true
,
      
onMoveShouldSetPanResponder: (evt, gestureState) => 
true
,
      
onMoveShouldSetPanResponderCapture: (evt, gestureState) => 
true
,
      
onPanResponderTerminationRequest: (evt, gestureState) => 
true
,  
  
      
//响应对应事件后的处理:
      
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

{

...this.myPanResponder.panHandlers}

 

5. 完善Render函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
render() {
    
return 
(
    
<View style={styles.himiViewStyle}
        
{...
this
.myPanResponder.panHandlers}
    
>
        
<Text style={styles.himiTextStyle}>Himi React Native 教程</Text>
        
<View style={styles.container}>
          
<Text style={styles.text}>{
this
.state.eventName}</Text>
          
<Text style={styles.text}>{
this
.state.pos}</Text>
        
</View> 
    
</View>
  
  
)}

 

6.用到的布局和样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var 
styles = StyleSheet.create({
  
container: {
    
flex: 1,
    
flexDirection: 
'row'
,
    
justifyContent: 
'center'
,
    
alignItems: 
'center'
,
    
backgroundColor: 
'#F5FCFF'
,
  
},
  
text: {
    
color:
'#f00'
,
    
fontSize:30,
  
},
  
himiViewStyle:{
    
flex: 1,
    
flexDirection: 
'column'
,
    
justifyContent: 
'center'
,
    
alignItems: 
'center'
,
    
backgroundColor: 
'#F5FCFF'
,
  
},
  
himiTextStyle:{
    
color:
'#f00'
,
    
fontSize:30,
    
marginTop:70,
  
},
});


效果如下:(点击查看动态效果)

如上是第一种形式,下面我们简单说下如何使用第二种形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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决定是否启用当前手势响应器
    
return 
true
;
  
  
_handleMoveShouldSetPanResponder(e, gestureState) {
    
return 
true
;
  
}
  
_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 : 
'另一个组件成了手势响应器时(当前组件触摸结束)的处理'
    
})
  
}


第二种形式就是将触摸响应绑定到我们自定义的函数,其他没有基本没区别。改动只有两点:

1. 绑定时修改成将触摸事件的回调绑定到我们自定义函数。

2. 添加每个响应的自定义函数。

效果如下:(点击查看动态效果)

 

    二:四种 Touchable 触摸组件     

 Touchable 一共有四种形式:

TouchableHighlight: 当按下的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。

TouchableNativeFeedback:(仅限Android平台) 在Android设备上,这个组件利用原生状态来渲染触摸的反馈。

TouchableOpacity: 当按下的时候,封装的视图的不透明度会降低。这个过程并不会真正改变视图层级,大部分情况下很容易添加到应用中而不会带来一些奇怪的副作用。

TouchableWithoutFeedback: 除非你有一个很好的理由,否则不要用这个组件。所有能够响应触屏操作的元素在触屏后都应该有一个视觉上的反馈(然而本组件没有任何视觉反馈),仍会触发触摸事件的响应

1. 添加Touchable的四种组件

1
2
3
4
5
6
7
8
9
10
import React, {
  
...
  
Image,
  
Alert,
  
TouchableHighlight,
  
TouchableNativeFeedback,
  
TouchableOpacity,
  
TouchableWithoutFeedback,
   
...
} from 
'react-native'
;


Himi这里还添加了Image和Alert两个组件:

Image 是图片组件,这里是为了测试效果,将Touchable发生在图片

Alert 弹窗提示组件,是为了通过弹窗,更好的展示出事件响应效果

2. 在Render添加如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<View style={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组件来实现。如:

1
2
3
4
5
6
<TouchableHighlight >  
      
<View>
            
<Text> t1 </Text>  
     
<Text> t2 </Text>  
      
</View>
 
</TouchableHighlight>
本文转自 xiaominghimi 51CTO博客,原文链接:http://blog.51cto.com/xiaominghimi/1772385,如需转载请自行联系原作者
你可能感兴趣的文章
深入了解passive-interface
查看>>
直接路由模式lvs
查看>>
分享oracle wdp查询,oracle重庆官方培训点查询,千万别被忽悠了
查看>>
rman异机恢复
查看>>
UVA 11294 Wedding 2sat
查看>>
无需解锁直接获权 索爱Xperia系列Root教程
查看>>
Centos 6.x/7.x yum安装php5.6.X
查看>>
linux备份
查看>>
运维自动化方案
查看>>
运维开发实战考题:计算教育网站投票排名
查看>>
windows 2003 普通用户 计划任务 拒绝访问
查看>>
网卡软中断调优
查看>>
android 双卡手机发短信/判断手机是否为双卡
查看>>
诡异的windows Workspace 2276,2269报错解决
查看>>
一些高效的Linux命令行操作(不断更新)
查看>>
mysql 5.6.28源码安装
查看>>
我的友情链接
查看>>
Linux挂载Windows文件系统
查看>>
2018.11.12-2018.11.18
查看>>
Hyper-V 3.0服务器虚拟化:打造坚固的云
查看>>