ReactNative: 使用Touchable触摸类组件
一、简介
在应用程序中,最灵魂的功能就是交互。通过给应用程序的组件添加事件来实现交互,进而提高用户体验。然而,ReactNative并不能像Web开发那样可以给大多数的标签元素绑定click事件,例如div、button、input等等,但是RN除了可以通过Text的onPress完成事件外,还是额外提供了4个组件来解决这个问题。这4个组件统称为“Touchable类组件”,也即触摸类组件,使用它们就可以像Text组件那样通过onPress使得其他任意组件都可以被点击。分别是TouchableHighlight、TouchableOpacity、TouchableWithoutFeedback、TouchableNativeFeedback。(注意:TouchableNativeFeedback用于安卓,此处不做解释)
二、区别
这三个组件都能实现触摸点击,进而完成事件交互,但是产生的交互过渡效果是有区别的,具体如下:
三、详请
1、TouchableHighlight,它拥有明显视觉交互效果,这种效果能够很友善地告知用户当前点击事件被触发了,从而避免重复点击。它的主要属性和事件如下:
//触摸时透明度的设置 avtiveOpacity //隐藏背景阴影时触发该事件 onHideUnderlay //出现背景阴影时触发该事件 onShowUnderlay //点击时背景阴影效果的背景颜色 underlayColor
使用效果如下:点击时背景颜色发生改变,有比较明显的交互提示
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, View, Text, TouchableHighlight } from 'react-native'; export default class ReactNativeDemo extends Component { render() { return ( <View style={style.flex}> <View style={style.touch}> <TouchableHighlight activeOpacity={0.5} underlayColor={'#E1F6FF'} onPress={() => alert("TouchableHighlight")} onHideUnderlay={() => console.log("--onHideUnderlay--")} onShowUnderlay={() => console.log("--onShowUnderlay--")} > <Text style={style.font}>Button</Text> </TouchableHighlight> </View> </View> ); } } const style = StyleSheet.create({ flex: { flex: 1, justifyContent: 'center', alignItems: 'center' }, touch:{ borderColor:'blue', borderWidth: 1, borderRadius: 4, justifyContent: 'center', alignItems: 'center' }, font:{ fontSize: 25, fontWeight: 'bold', color:'red' } }); AppRegistry.registerComponent('ReactNativeDemo', () => ReactNativeDemo);
2019-12-13 14:21:02.747 [info][tid:com.facebook.react.JavaScript] --onShowUnderlay-- 2019-12-13 14:21:04.767 [info][tid:com.facebook.react.JavaScript] --onHideUnderlay-- 2019-12-13 14:21:04.768 [info][tid:com.facebook.react.JavaScript] --onShowUnderlay-- 2019-12-13 14:21:04.869 [info][tid:com.facebook.react.JavaScript] --onHideUnderlay--
2、TouchableOpacity,它也能给出交互提示,不过它不能设置背景色,只能设置通过透明度,反而更加方便。它仅有一个属性。
//触摸时透明度的设置 avtiveOpacity
使用效果如下:点击时透明度发生改变,也有较明显的交互提示
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, View, Text, TouchableOpacity } from 'react-native'; export default class ReactNativeDemo extends Component { render() { return ( <View style={style.flex}> <View style={style.touch}> <TouchableOpacity activeOpacity={0.2} onPress={() => alert("TouchableOpacity")} > <Text style={style.font}>Button</Text> </TouchableOpacity> </View> </View> ); } } const style = StyleSheet.create({ flex: { flex: 1, justifyContent: 'center', alignItems: 'center' }, touch:{ borderColor:'blue', borderWidth: 1, borderRadius: 4, justifyContent: 'center', alignItems: 'center' }, font:{ fontSize: 25, fontWeight: 'bold', color:'red' } }); AppRegistry.registerComponent('ReactNativeDemo', () => ReactNativeDemo);
3、TouchableWithoutFeedback,使用它绑定事件,不会有明显的交互提示,就跟Web交互一样,而不是Native交互,除非特殊情况,不推荐使用。它不能直接嵌套子组件Text组件,必须先隔一个父组件,否则自身事件属性不能触发,它支持三个自身属性事件如下:
//长按事件 onLongPress //触摸进入事件 onPressIn //触摸释放事件 onPressOut
使用效果如下:发现交互时无任何明显提示,长按打印日至
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, View, Text, TouchableWithoutFeedback } from 'react-native'; export default class ReactNativeDemo extends Component { render() { return ( <View style={style.flex}> <View style={style.touch}> <TouchableWithoutFeedback onPress={() => alert("TouchableWithoutFeedback")} onLongPress={() => console.log("--onLongPress--")} onPressIn={() => console.log("--onPressIn--")} onPressOut={() => console.log("--onPressOut--")} > <View><Text style={style.font}>Button</Text></View> /*Text嵌套在View组件中,然后在嵌套到该触摸类组件中*/ </TouchableWithoutFeedback> </View> </View> ); } } const style = StyleSheet.create({ flex: { flex: 1, justifyContent: 'center', alignItems: 'center' }, touch:{ borderColor:'blue', borderWidth: 1, borderRadius: 4, justifyContent: 'center', alignItems: 'center' }, font:{ fontSize: 25, fontWeight: 'bold', color:'red' } }); AppRegistry.registerComponent('ReactNativeDemo', () => ReactNativeDemo);
2019-12-13 14:52:48.796 [info][tid:com.facebook.react.JavaScript] --onPressIn-- 2019-12-13 14:52:49.301 [info][tid:com.facebook.react.JavaScript] --onLongPress-- 2019-12-13 14:52:50.465 [info][tid:com.facebook.react.JavaScript] --onPressOut-- 2019-12-13 14:52:52.096 [info][tid:com.facebook.react.JavaScript] --onPressIn-- 2019-12-13 14:52:52.100 [info][tid:com.facebook.react.JavaScript] --onPressOut--