You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native响应式3x3井字棋网格边框绘制问题求助

解决React Native 3x3井字棋网格无外边框问题

以下两种方案都能实现仅内部有网格线、侧边无外边框的适配多屏幕的井字棋布局:


方案一:基于方块位置添加局部边框

通过判断每个方块在3x3网格中的位置,仅给需要的边添加边框,避免外边框出现。同时用循环生成方块,减少冗余代码:

import { View, Text, StyleSheet, Dimensions } from 'react-native';

const { width: DeviceWidth } = Dimensions.get('window');

export default function TicTacToe() {
  const board = ['X', 'O', 'X', 'X', 'O', 'O', 'X', 'X', 'O'];

  // 根据方块索引判断需要的边框样式
  const getBoxBorder = (index) => {
    const borderStyles = {};
    // 非第三列的方块,添加右边框(形成两条竖分隔线)
    if (index % 3 !== 2) {
      borderStyles.borderRightWidth = 2;
      borderStyles.borderRightColor = '#000';
    }
    // 前两行的方块,添加下边框(形成两条横分隔线)
    if (index < 6) {
      borderStyles.borderBottomWidth = 2;
      borderStyles.borderBottomColor = '#000';
    }
    return borderStyles;
  };

  return (
    <View style={styles.container}>
      <View style={styles.boxContainer}>
        {board.map((value, index) => (
          <View 
            key={index} 
            style={[styles.box, getBoxBorder(index)]}
          >
            <Text style={styles.boxText}>{value}</Text>
          </View>
        ))}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    width: DeviceWidth * 0.3,
    height: DeviceWidth * 0.3,
    alignItems: 'center',
    justifyContent: 'center', // 让文字垂直居中
  },
  boxText: {
    fontSize: DeviceWidth * 0.15,
    fontWeight: 'bold',
  },
  boxContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
  },
});

方案二:绝对定位绘制内部线条

直接在容器中通过绝对定位画两条竖线和两条横线,无需给方块加边框,逻辑更简洁:

import { View, Text, StyleSheet, Dimensions } from 'react-native';

const { width: DeviceWidth } = Dimensions.get('window');
const gridSize = DeviceWidth * 0.9; // 网格占屏幕90%宽度
const cellSize = gridSize / 3; // 每个方块的尺寸

export default function TicTacToe() {
  const board = ['X', 'O', 'X', 'X', 'O', 'O', 'X', 'X', 'O'];

  return (
    <View style={styles.container}>
      <View style={styles.boxContainer}>
        {/* 生成9个方块 */}
        {board.map((value, index) => (
          <View key={index} style={styles.box}>
            <Text style={styles.boxText}>{value}</Text>
          </View>
        ))}
        {/* 绘制两条竖分隔线 */}
        <View style={[styles.line, styles.vertical, { left: cellSize }]} />
        <View style={[styles.line, styles.vertical, { left: cellSize * 2 }]} />
        {/* 绘制两条横分隔线 */}
        <View style={[styles.line, styles.horizontal, { top: cellSize }]} />
        <View style={[styles.line, styles.horizontal, { top: cellSize * 2 }]} />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  boxContainer: {
    width: gridSize,
    height: gridSize, // 保证网格是正方形
    flexDirection: 'row',
    flexWrap: 'wrap',
    position: 'relative', // 让内部线条以容器为定位基准
  },
  box: {
    width: cellSize,
    height: cellSize,
    alignItems: 'center',
    justifyContent: 'center',
  },
  boxText: {
    fontSize: cellSize * 0.5,
    fontWeight: 'bold',
  },
  line: {
    position: 'absolute',
    backgroundColor: '#000',
  },
  vertical: {
    width: 2,
    height: gridSize,
  },
  horizontal: {
    width: gridSize,
    height: 2,
  },
});

方案对比

  • 方案一:适合需要给单个方块添加交互样式(如点击高亮)的场景,每个方块独立可控
  • 方案二:线条统一管理,代码更简洁,适合仅需基础网格的情况

内容的提问来源于stack exchange,提问作者akira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:25:32