我有一个二维数组,呈现一个正方形网格。网格应该是一个正方形,并且每个正方形都应该是一个正方形,如aspectRatio 为1。
基本网格如下所示:
function Grid() {
const grid = [
["", "", "", "", ""],
["", "", "", "", ""],
["", "", "", "", ""],
["", "", "", "", ""],
["", "", "", "", ""],
]
return (
<View>
<View style={styles.container}>
{grid.map((row, i) => {
return (
<View key={i} style={styles.row}>
{row.map((square, j) => {
return <View style={styles.square}>{square}</View>
})}
</View>
);
})}
</View>
</View>
)
}
const getStyles = (dimension: number) => {
return StyleSheet.create({
container: {
width: "100%",
},
row: {
flexDirection: "row",
gap: 4,
marginBottom: 4,
width: "100%",
},
square: {
flex: 1,
display: "flex",
justifyContent: "center",
alignItems: "center",
aspectRatio: 1,
}
});
};
方块的内容目前无关紧要,这将渲染 5x5 的方块网格。
间隙和边距会产生边框的错觉,但这样页面两侧就没有边框了。
问题是,根据网格的大小(5x5、6x6 等),行之间会存在随机间隙。这几乎就像数学没有检验出来一样,就像屏幕宽度与正方形/列/行的数量混合以及间隙/边距大小使得不可能渲染完美的正方形。
列之间没有间隙:
列之间的间隙会在行之间产生不必要的小间隙:
这可能吗?有没有办法找出渲染正方形的完美纵横比,同时扩展屏幕的整个宽度?我觉得这应该是可能的,或者应该有办法让纵横比填满可用空间。
我不介意正方形是否不完美,只要行或列之间没有不需要的间隙,并且网格覆盖屏幕的整个宽度。
我没有遇到你有奇怪差距的问题,但也许我理解你的要求是错误的。无论如何,这是我尝试创建延伸到屏幕宽度的抓地力。它基本上使用了所有原始代码,并丢弃了一些样式。
import * as React from 'react';
import {
StyleSheet,
View,
TextInput,
Text,
TouchableOpacity,
} from 'react-native';
const genGrid = (row, col, defaultVal = '') => {
return [...Array(parseInt(row, 10))].map(_ =>
Array(parseInt(col, 10)).fill(defaultVal),
);
};
const App = () => {
const [rowStr, setRowStr] = React.useState('4');
const [colStr, setColStr] = React.useState('4');
const [grid, setGrid] = React.useState(genGrid(4, 4));
const onButtonPress = () => setGrid(genGrid(rowStr, colStr));
return (
<View style={styles.screen}>
<View style={styles.inputContainer}>
<Text>Row: </Text>
<TextInput
style={styles.textInput}
value={rowStr}
onChangeText={setRowStr}
/>
</View>
<View style={styles.inputContainer}>
<Text>Col: </Text>
<TextInput
style={styles.textInput}
value={colStr}
onChangeText={setColStr}
/>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={onButtonPress}>
<Text>Generate Grid</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
{grid.map((row, i) => {
return (
<View key={i} style={styles.row}>
{row.map((square, j) => {
return (
<View key={j} style={styles.square}>
{square}
</View>
);
})}
</View>
);
})}
</View>
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
},
container: {
width: '100%',
},
inputContainer: {
flexDirection: 'row',
justifyContent: 'center',
marginVertical: 10,
},
textInput: {
width: 50,
borderBottomWidth: 1,
textAlign: 'center',
},
buttonContainer: {
alignItems: 'center',
marginVertical: 10,
},
button: {
justifyContent: 'center',
alignItems: 'center',
borderWidth: 2,
borderRadius: 30,
width: '30%',
height: 40,
},
row: {
flexDirection: 'row',
marginVertical: 2,
width: '100%',
// borderWidth: 2,
// borderColor: 'blue',
},
square: {
flex: 1,
marginHorizontal: 2,
aspectRatio: 1,
backgroundColor: 'red',
// borderWidth: 2,
// borderColor: 'red',
},
});
export default App;