纵横比在兄弟元素之间造成间隙

问题描述 投票:0回答:1

我有一个二维数组,呈现一个正方形网格。网格应该是一个正方形,并且每个正方形都应该是一个正方形,如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 等),行之间会存在随机间隙。这几乎就像数学没有检验出来一样,就像屏幕宽度与正方形/列/行的数量混合以及间隙/边距大小使得不可能渲染完美的正方形。

列之间没有间隙:

列之间的间隙会在行之间产生不必要的小间隙:

这可能吗?有没有办法找出渲染正方形的完美纵横比,同时扩展屏幕的整个宽度?我觉得这应该是可能的,或者应该有办法让纵横比填满可用空间。

我不介意正方形是否不完美,只要行或列之间没有不需要的间隙,并且网格覆盖屏幕的整个宽度。

react-native aspect-ratio
1个回答
0
投票

我没有遇到你有奇怪差距的问题,但也许我理解你的要求是错误的。无论如何,这是我尝试创建延伸到屏幕宽度的抓地力。它基本上使用了所有原始代码,并丢弃了一些样式。

演示

亲自尝试一下

沙盒

源代码

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;

© www.soinside.com 2019 - 2024. All rights reserved.