Skip to content

React Native - 按钮

React Native 提供了几种创建交互式按钮和可触控区域的方式。本章节将介绍基础的 Button 组件,以及更具可定制性的触控组件,如 TouchableOpacity、TouchableHighlight、TouchableWithoutFeedback 和现代的 Pressable。

Button 组件是一个简单的、预设样式的按钮。它适用于快速使用,但定制性有限。

ButtonExample.js

import React from 'react';
import { View, Button, Alert, StyleSheet } from 'react-native';
const ButtonExample = () => {
const handlePress = () => {
Alert.alert('Button Pressed!', 'You tapped the basic button.');
};
return (
<View style={styles.container}>
<Button
title="Press Me"
onPress={handlePress}
color="#841584" // 可选:自定义颜色 (iOS 文本颜色,Android 背景颜色)
// accessibilityLabel="Learn more about this purple button" // 用于无障碍功能
// disabled={true} // 禁用按钮
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
}
});
export default ButtonExample;

这将渲染一个平台标准样式的按钮。在 iOS 上,color 属性改变文本颜色。在 Android 上,color 改变背景颜色 (适用于 Android API level 21+)。

TouchableOpacity 是一个包装器,当按下时会降低其内容的透明度,提供视觉反馈。它具有高度的可定制性,因为你可以设置其子组件的样式。

TouchableOpacityExample.js

import React from 'react';
import { View, TouchableOpacity, Text, StyleSheet, Alert } from 'react-native';
const TouchableOpacityExample = () => {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.touchableOpacityButton}
onPress={() => Alert.alert('TouchableOpacity', 'Opacity effect on press!')}
activeOpacity={0.7} // 按下时的透明度,默认为 0.2
>
<Text style={styles.buttonText}>Custom Button (Opacity)</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20
},
touchableOpacityButton: {
backgroundColor: '#007bff',
paddingVertical: 12,
paddingHorizontal: 25,
borderRadius: 8,
elevation: 3, // Android shadow
shadowColor: '#000', // iOS shadow
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
textAlign: 'center',
}
});
export default TouchableOpacityExample;

按下此按钮时,其透明度会暂时降低,提供一种常见的触摸反馈效果。

TouchableHighlight 在按下时会加深其内容背景(下层颜色)。你必须提供 underlayColor 属性。

TouchableHighlightExample.js

import React from 'react';
import { View, TouchableHighlight, Text, StyleSheet, Alert } from 'react-native';
const TouchableHighlightExample = () => {
return (
<View style={styles.container}>
<TouchableHighlight
style={styles.touchableHighlightButton}
onPress={() => Alert.alert('TouchableHighlight', 'Highlight effect on press!')}
underlayColor="#0056b3" // 按下时显示的颜色
>
<Text style={styles.buttonText}>Custom Button (Highlight)</Text>
</TouchableHighlight>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20
},
touchableHighlightButton: {
backgroundColor: '#17a2b8',
paddingVertical: 12,
paddingHorizontal: 25,
borderRadius: 8,
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
textAlign: 'center',
}
});
export default TouchableHighlightExample;

按下时,按钮的背景将变为 underlayColor 指定的颜色。

Pressable 是一个更现代、更通用的核心组件,用于检测其定义子组件上的各种按下交互阶段。它提供了对视觉反馈和交互状态(例如,按下、悬停、聚焦)更细粒度的控制。

PressableExample.js

import React from 'react';
import { View, Pressable, Text, StyleSheet, Alert } from 'react-native';
const PressableExample = () => {
return (
<View style={styles.container}>
<Pressable
onPress={() => Alert.alert('Pressable', 'Standard press!')}
onLongPress={() => Alert.alert('Pressable', 'Long press!')}
// style 属性可以是一个函数,根据按下状态改变样式
style={({ pressed }) => [
styles.pressableButton,
{ backgroundColor: pressed ? 'rgb(210, 230, 255)' : '#28a745' }
]}
// android_ripple={{ color: 'grey', borderless: false }}
// hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
>
{({ pressed }) => (
<Text style={styles.buttonText}>
{pressed ? 'Pressed!' : 'Press Me (Pressable)'}
</Text>
)}
</Pressable>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20
},
pressableButton: {
paddingVertical: 12,
paddingHorizontal: 25,
borderRadius: 8,
elevation: 3,
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
textAlign: 'center',
}
});
export default PressableExample;

Pressable 提供了以下功能:

  • onPressIn、onPressOut、onLongPress 等事件。
  • 函数式 style 和 children 属性,可根据交互状态 (pressed) 动态改变。
  • android_ripple 用于实现 Android 的涟漪效果。
  • hitSlop 可扩展触摸区域而不改变布局。

TouchableNativeFeedback(仅限 Android)

Section titled “TouchableNativeFeedback(仅限 Android)”

此组件提供 Android 原生的涟漪效果。它仅适用于 Android。对于跨平台解决方案,优先推荐使用带有 android_ripple 的 Pressable,或者使用 TouchableOpacity 以获得一致的体验。

// TouchableNativeFeedbackExample.js(仅限 Android)
import React from 'react';
import { View, TouchableNativeFeedback, Text, StyleSheet, Platform, Alert } from 'react-native';
const TouchableNativeFeedbackExample = () => {
if (Platform.OS === 'android') {
return (
<View style={styles.container}>
<TouchableNativeFeedback
onPress={() => Alert.alert('Native Feedback', 'Ripple effect!')}
background={TouchableNativeFeedback.Ripple('rgba(255,255,255,0.3)', false)} // 颜色,是否无边界
useForeground={true} // 涟漪效果在前景色,适用于圆角
>
<View style={styles.nativeFeedbackButton}>
<Text style={styles.buttonText}>Button (Native Ripple)</Text>
</View>
</TouchableNativeFeedback>
</View>
);
}
return (
<View style={styles.container}><Text>TouchableNativeFeedback is Android-only.</Text></View>
);
};
// (样式类似于其他示例)
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
nativeFeedbackButton: { backgroundColor: '#ffc107', paddingVertical: 12, paddingHorizontal: 25, borderRadius: 8, alignItems: 'center', justifyContent: 'center' },
buttonText: { color: '#212529', fontSize: 16, fontWeight: 'bold' }
});
export default TouchableNativeFeedbackExample;

此组件处理触摸事件但不提供任何视觉反馈。它适用于创建不希望有默认反馈的自定义触摸交互。

// TouchableWithoutFeedbackExample.js
import React from 'react';
import { View, TouchableWithoutFeedback, Text, StyleSheet, Alert } from 'react-native';
const TouchableWithoutFeedbackExample = () => {
return (
<View style={styles.container}>
<TouchableWithoutFeedback onPress={() => Alert.alert('No Feedback', 'Touched!')}>
<View style={styles.noFeedbackView}>
<Text>Touch Area (No Visual Feedback)</Text>
</View>
</TouchableWithoutFeedback>
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
noFeedbackView: { padding: 20, backgroundColor: '#e9ecef', borderWidth: 1, borderColor: '#ced4da' }
});
export default TouchableWithoutFeedbackExample;

选择合适的触控组件取决于期望的用户体验和定制程度。对于新开发项目,Pressable 通常是最好的通用选择。了解更多信息:https://reactnative.dev/docs/handling-touches