【REACT NATIVE 系列教程之一】触摸事件的两种形式与四种TOUCHABLE组件详解

简介:

本文是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,
   },
});


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

user

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

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. 添加每个响应的自定义函数。

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

user2

 

    二:四种 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之外的三种形式。

根据反馈的形式,大家可以自行设置其透明度、背景色、样式等。

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

user4

注意: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,如需转载请自行联系原作者
目录
相关文章
|
1天前
|
移动开发 前端开发 JavaScript
React音频播放列表组件:常见问题、易错点与解决方案
本文介绍了在React中实现音频播放列表时常见的挑战及解决方案。通过基础实现、常见问题分析和最佳实践,帮助开发者避免状态管理、生命周期控制和事件处理中的陷阱。关键点包括使用`useRef`操作音频元素、`useState`同步播放状态、全局状态管理防止多音频同时播放、以及通过`useEffect`清理资源。还提供了代码示例和跨浏览器兼容性处理方法,确保高效实现功能并减少调试时间。
65 30
|
3天前
|
移动开发 前端开发 UED
React 音频音量控制组件 Audio Volume Control
在现代Web应用中,音频播放功能不可或缺。React以其声明式编程和组件化开发模式,非常适合构建复杂的音频音量控制组件。本文介绍了如何使用HTML5 `&lt;audio&gt;`元素与React结合,实现直观的音量控制系统,并解决了常见问题如音量范围不合理、初始音量设置及性能优化等,帮助开发者打造优秀的音频播放器。
56 27
|
4天前
|
移动开发 前端开发 UED
React 音频进度条组件 Audio Progress Bar
在现代Web开发中,音频播放功能不可或缺。使用React构建音频进度条组件,不仅能实现播放控制和拖动跳转,还能确保代码的可维护性和复用性。本文介绍了如何利用HTML5 `&lt;audio&gt;`标签的基础功能、解决获取音频时长和当前时间的问题、动态更新进度条样式,并避免常见错误如忘记移除事件监听器和忽略跨浏览器兼容性。通过这些方法,开发者可以打造高质量的音频播放器,提升用户体验。
36 6
|
5天前
|
移动开发 前端开发 开发者
React 音频播放控制组件 Audio Controls
本文介绍了如何使用React构建音频播放控制组件,涵盖HTML5 `&lt;audio&gt;`标签和React组件化思想的基础知识。针对常见问题如播放状态管理、进度条更新不准确及跨浏览器兼容性,提供了详细的解决方案和代码示例。同时,还总结了易错点及避免方法,如确保音频加载完成再操作、处理音频错误等,帮助开发者实现稳定且功能强大的音频播放器。
38 11
|
8天前
|
前端开发
React 中高阶组件的原理是什么?
React 中高阶组件的原理是什么?
|
8天前
|
前端开发
在 React 中使用高阶组件时,如何避免命名冲突?
在 React 中使用高阶组件时,如何避免命名冲突?
71 56
|
8天前
|
前端开发 开发者
除了函数组件和类组件,React 还有其他创建组件的方式吗?
除了函数组件和类组件,React 还有其他创建组件的方式吗?
|
8天前
|
前端开发
如何在React Router中定义404错误页面组件?
如何在React Router中定义404错误页面组件?
74 57
|
8天前
|
前端开发 JavaScript
除了使用Route组件,React Router还有其他方式处理404错误页面吗
除了使用Route组件,React Router还有其他方式处理404错误页面吗
|
11天前
|
人工智能 自然语言处理 前端开发
Flame:开源AI设计图转代码模型!生成React组件,精准还原UI+动态交互效果
Flame 是一款开源的多模态 AI 模型,能够将 UI 设计图转换为高质量的现代前端代码,支持 React 等主流框架,具备动态交互、组件化开发等功能,显著提升前端开发效率。
253 1