Skip to content

Button / TouchableOpacity(按钮)

React Native 核心基础组件

在 React Native 中,按钮是用户交互的重要元素。React Native 提供了多种按钮组件,其中最常用的是 ButtonTouchableOpacity

1. Button 组件

基本用法

Button 是 React Native 内置的按钮组件,使用方法非常简单。

jsx
import React from 'react';
import { Button, View, StyleSheet } from 'react-native';

export default function ButtonExample() {
  return (
    <View style={styles.container}>
      <Button
        title="点击我"
        onPress={() => alert('按钮被点击了!')}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

属性

属性描述示例
title按钮文本title="点击我"
onPress点击事件处理函数onPress={() => alert('点击了')}
style按钮样式style={ { margin: 10 } }
color按钮颜色color="#4CAF50"
disabled是否禁用disabled={true}
testID测试 IDtestID="my-button"

示例

jsx
import React, { useState } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';

export default function ButtonStatesExample() {
  const [count, setCount] = useState(0);

  return (
    <View style={styles.container}>
      <Text style={styles.count}>{count}</Text>
      <Button
        title="增加计数"
        onPress={() => setCount(count + 1)}
        color="#4CAF50"
      />
      <Button
        title="重置计数"
        onPress={() => setCount(0)}
        color="#f44336"
        style={styles.button}
      />
      <Button
        title="禁用按钮"
        onPress={() => alert('这个按钮被禁用了')}
        disabled={true}
        style={styles.button}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  count: {
    fontSize: 24,
    marginBottom: 20,
  },
  button: {
    marginTop: 10,
  },
});

2. TouchableOpacity 组件

TouchableOpacity 是一个更灵活的按钮组件,它可以包含任何子元素,并且可以自定义样式。

基本用法

jsx
import React from 'react';
import { TouchableOpacity, Text, View, StyleSheet } from 'react-native';

export default function TouchableOpacityExample() {
  return (
    <View style={styles.container}>
      <TouchableOpacity
        style={styles.button}
        onPress={() => alert('按钮被点击了!')}
      >
        <Text style={styles.buttonText}>点击我</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  button: {
    backgroundColor: '#4CAF50',
    paddingHorizontal: 20,
    paddingVertical: 10,
    borderRadius: 5,
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
  },
});

属性

属性描述示例
activeOpacity按下时的透明度activeOpacity={0.7}
onPress点击事件处理函数onPress={() => alert('点击了')}
onLongPress长按事件处理函数onLongPress={() => alert('长按了')}
style容器样式style={ { backgroundColor: '#4CAF50' } }
disabled是否禁用disabled={true}
testID测试 IDtestID="my-touchable"

示例

jsx
import React, { useState } from 'react';
import { TouchableOpacity, Text, View, StyleSheet, Image } from 'react-native';

export default function TouchableOpacityAdvanced() {
  const [count, setCount] = useState(0);

  return (
    <View style={styles.container}>
      <Text style={styles.count}>{count}</Text>
      
      {/* 基本按钮 */}
      <TouchableOpacity
        style={styles.button}
        onPress={() => setCount(count + 1)}
        activeOpacity={0.8}
      >
        <Text style={styles.buttonText}>增加计数</Text>
      </TouchableOpacity>
      
      {/* 带图标的按钮 */}
      <TouchableOpacity
        style={styles.iconButton}
        onPress={() => setCount(0)}
      >
        <Image
          source={{ uri: 'https://via.placeholder.com/20' }}
          style={styles.icon}
        />
        <Text style={styles.iconButtonText}>重置计数</Text>
      </TouchableOpacity>
      
      {/* 禁用的按钮 */}
      <TouchableOpacity
        style={[styles.button, styles.disabledButton]}
        onPress={() => alert('这个按钮被禁用了')}
        disabled={true}
      >
        <Text style={styles.disabledButtonText}>禁用按钮</Text>
      </TouchableOpacity>
      
      {/* 长按按钮 */}
      <TouchableOpacity
        style={styles.button}
        onPress={() => alert('点击了')}
        onLongPress={() => alert('长按了')}
      >
        <Text style={styles.buttonText}>点击或长按我</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  count: {
    fontSize: 24,
    marginBottom: 20,
  },
  button: {
    backgroundColor: '#4CAF50',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    marginTop: 10,
    width: '100%',
    alignItems: 'center',
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '500',
  },
  iconButton: {
    flexDirection: 'row',
    backgroundColor: '#2196F3',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    marginTop: 10,
    width: '100%',
    alignItems: 'center',
  },
  icon: {
    width: 20,
    height: 20,
    marginRight: 10,
  },
  iconButtonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '500',
  },
  disabledButton: {
    backgroundColor: '#cccccc',
  },
  disabledButtonText: {
    color: '#666666',
    fontSize: 16,
  },
});

3. TouchableHighlight 组件

TouchableHighlight 是另一个常用的触摸组件,它在按下时会显示一个高亮效果。

基本用法

jsx
import React from 'react';
import { TouchableHighlight, Text, View, StyleSheet } from 'react-native';

export default function TouchableHighlightExample() {
  return (
    <View style={styles.container}>
      <TouchableHighlight
        style={styles.button}
        onPress={() => alert('按钮被点击了!')}
        activeOpacity={0.8}
        underlayColor="#388E3C"
      >
        <Text style={styles.buttonText}>点击我</Text>
      </TouchableHighlight>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  button: {
    backgroundColor: '#4CAF50',
    paddingHorizontal: 20,
    paddingVertical: 10,
    borderRadius: 5,
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
  },
});

属性

属性描述示例
activeOpacity按下时的透明度activeOpacity={0.7}
onPress点击事件处理函数onPress={() => alert('点击了')}
onLongPress长按事件处理函数onLongPress={() => alert('长按了')}
style容器样式style={ { backgroundColor: '#4CAF50' } }
underlayColor按下时的背景颜色underlayColor="#388E3C"
disabled是否禁用disabled={true}
testID测试 IDtestID="my-touchable"

4. 按钮样式最佳实践

1. 统一的按钮样式

创建一个按钮样式文件,定义统一的按钮样式。

jsx
// styles/buttons.js
import { StyleSheet } from 'react-native';

export const buttonStyles = StyleSheet.create({
  primary: {
    backgroundColor: '#4CAF50',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  secondary: {
    backgroundColor: '#2196F3',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  danger: {
    backgroundColor: '#f44336',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  disabled: {
    backgroundColor: '#cccccc',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  text: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '500',
  },
  disabledText: {
    color: '#666666',
    fontSize: 16,
  },
});

2. 可复用的按钮组件

创建一个可复用的按钮组件。

jsx
// components/Button.js
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
import { buttonStyles } from '../styles/buttons';

export default function Button({ 
  title, 
  onPress, 
  style, 
  textStyle, 
  disabled = false, 
  variant = 'primary',
  ...props 
}) {
  return (
    <TouchableOpacity
      style={[
        buttonStyles[variant],
        disabled && buttonStyles.disabled,
        style,
      ]}
      onPress={onPress}
      disabled={disabled}
      {...props}
    >
      <Text 
        style={[
          buttonStyles.text,
          disabled && buttonStyles.disabledText,
          textStyle,
        ]}
      >
        {title}
      </Text>
    </TouchableOpacity>
  );
}

3. 使用示例

jsx
import React from 'react';
import { View, StyleSheet } from 'react-native';
import Button from './components/Button';

export default function ButtonExample() {
  return (
    <View style={styles.container}>
      <Button
        title="主要按钮"
        onPress={() => alert('主要按钮被点击了')}
        variant="primary"
        style={styles.button}
      />
      <Button
        title="次要按钮"
        onPress={() => alert('次要按钮被点击了')}
        variant="secondary"
        style={styles.button}
      />
      <Button
        title="危险按钮"
        onPress={() => alert('危险按钮被点击了')}
        variant="danger"
        style={styles.button}
      />
      <Button
        title="禁用按钮"
        onPress={() => alert('这个按钮被禁用了')}
        disabled={true}
        style={styles.button}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  button: {
    width: '100%',
    marginVertical: 8,
  },
});

5. 常见问题与解决方案

问题 1:按钮没有点击效果

问题:按钮点击时没有视觉反馈。

解决方案

  • 使用 TouchableOpacity 并设置 activeOpacity 属性
  • 使用 TouchableHighlight 并设置 underlayColor 属性

问题 2:按钮样式不生效

问题:自定义按钮样式不生效。

解决方案

  • 确保样式对象的结构正确
  • 使用 StyleSheet.create 创建样式
  • 检查样式优先级,确保没有被其他样式覆盖

问题 3:按钮点击事件不触发

问题:按钮点击时事件不触发。

解决方案

  • 检查 onPress 属性是否正确设置
  • 确保按钮没有被禁用(disabled={false}
  • 检查按钮是否被其他组件遮挡

6. 总结

在 React Native 中,按钮是用户交互的重要元素。Button 组件简单易用,适合基本场景;TouchableOpacity 更加灵活,可以自定义样式和包含任何子元素;TouchableHighlight 则提供了按下时的高亮效果。

通过创建统一的按钮样式和可复用的按钮组件,可以提高代码的可维护性和一致性。在实际开发中,根据具体需求选择合适的按钮组件,并注意处理常见问题,以确保按钮的正常工作和良好的用户体验。

© 2026 编程马·菜鸟教程 版权所有