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--

 

posted @ 2019-12-13 15:23  XYQ全哥  阅读(427)  评论(0编辑  收藏  举报