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
相关产品推荐
相关产品推荐

