如何在 React Native 中的父组件内指定位置显示多个子组件?

3
我正在尝试在父组件内的特定位置(基于某些计算)呈现多个子组件。给出垂直位置的计算看起来正确,但是组件未显示在应该显示的位置上。我已经尝试了绝对窗口位置和相对组件位置,但都没有成功。
父组件如下所示:
const top = 170;
const bottom = 10;
const left = 10;
const right = 10;

const styles = StyleSheet.create({
  grid: {
    flex: 1,
    position: 'absolute',
    top: top,
    height: Dimensions.get('window').height - top - bottom,
    width: Dimensions.get('window').width - left - right,
    borderLeftColor: 'black',
    borderLeftWidth: 1,
    borderBottomColor: 'black',
    borderBottomWidth: 1
  }
});

const DrawGrid: React.FC<IDrawGrid> = ({ maxDistance, elements }) => {
  const [gridSize, setGridSize] = useState<LayoutRectangle>();

  return (
    <View style={styles.grid} onLayout={(event) => {
      setGridSize(event.nativeEvent.layout);
    }}>
      {elements.map((element, index) => {
        return (
          <DrawElement element={element} maxDistance={maxDistance} gridSize={gridSize} index={index * 2} />
        )
      })}
    </View>
  );
};

渲染所有元素的子组件如下所示:

const top = 170;
const bottom = 20;
const left = 10;
const right = 10;

const styles = StyleSheet.create({
  elementContainer: {
    borderLeftColor: 'red',
    borderLeftWidth: 1,
    borderTopColor: 'red',
    borderTopWidth: 1,
    borderRightColor: 'red',
    borderRightWidth: 1,
    borderBottomColor: 'red',
    borderBottomWidth: 1,
    borderRadius: 5,
    padding: 2,
    position: 'relative',
    alignSelf: 'flex-start'
  }
});

const getVerticalPosition = (someDistance: number, maxDistance: number, height: number) => {
  if (!someDistance || !maxDistance) return { top: 0 };

  const topDistance = (1 - (someDistance / maxDistance)) * height;
  return { top: topDistance };
};

const DrawElement: React.FC<IDrawElement> = ({ maxDistance, element, gridSize, index }) => {
  const styleVertical = getVerticalPosition(someDistance, maxDistance, gridSize.height);

  return (
    <View key={key} style={[styles.elementContainer, styleVertical]}>
      <Text>top: {styleVertical.top.toFixed(2)}</Text>
    </View>
  );
};

我能看到getVerticalPosition返回了正确的值,但元素从未出现在预期位置。在下面的快照中,我打印了每个元素的顶部值,我们可以看到它根本没有被尊重。(水平位置超出了问题的范围)enter image description here 我最初的想法是我某种方式弄乱了样式,我还尝试给每个元素赋予不同的zindex,但都没有成功。有什么想法吗?任何帮助将不胜感激,谢谢!

你能提供一些可视化的例子来展示它是什么样子吗?或者在代码沙盒中提供交互式的例子。 - Николай Гольцев
我刚刚上传了我设备上所看到的快照,对此感到抱歉。 - Enric Piferrer Torres
我真的不明白为什么你要设置alignSelf和相对位置。我会取消alignSelf并将位置设置为绝对定位。 - Giovanni Esposito
alignSelf可以帮助组件与其内容一样大。如果我将其移除,垂直定位组件的问题仍未解决。我使用相对定位是因为我想让子元素相对于父元素定位。我也尝试过计算绝对位置,但这也无法解决问题... - Enric Piferrer Torres
1个回答

0

我认为你不理解React Native中的布局类型如何工作。 这里是一个链接:https://reactnative.dev/docs/flexbox#absolute--relative-layout。 主要问题是每个子元素相对于自己的初始位置具有 relative 位置。

默认情况下,React Native 中的所有元素都具有 position 等于 relative,因此您不需要将其放在样式定义中。

为了更好地理解 relative 位置方案,我建议您考虑它的呈现过程分两步:

  1. 没有任何 top, left, bottom, right 属性的呈现子元素;
  2. 根据子元素当前位置的 top, left, bottom, right 属性将子元素移动;

想象一下,您有这样的代码:

<View style={styles.parent}>
  <View style={styles.firstChild}/>
  <View style={styles.secondChild}/>
</View>

const styles = StyleSheet.create({
  parent: {
    top: 100,
    flex: 1,
  },
  firstChild: {
    top: 100,
    height: 50,
  },
  secondChild: {
    top: 80,
    height: 70,
  },
});

如果我们将上述两个步骤应用于这个例子,它会变成这样:

enter image description here   enter image description here

为了解决您的问题,您需要将 absolute 定位方案应用于子元素。只有使用 absolute 定位方案才能将元素放置在父元素当前位置下方 100 点的地方,例如使用 top: 100 属性。
希望这对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接