响应式React原生Web布局

xvw2m8pv  于 2022-11-25  发布在  React
关注(0)|答案(2)|浏览(204)

我正在尝试从一个React原生项目创建一个 Jmeter 板布局。想法是保持Android、iOS和Web的大部分代码相似,只有布局或导航风格会发生变化。但我发现在Web中创建这种类型的布局很容易,但在不重新渲染的情况下使其响应很难。
我已经实现了这一点,通过手动计算窗口的高度和宽度通过以下代码
Dimensions.get('window').width Dimensions.get('window').height
并通过eventListener不断更新状态,以便它一次又一次地重新呈现整个页面。
Dimensions.addEventListener("change", this.updateScreen);
有没有办法我可以简单地使用一些%值来填充屏幕。现在如果我使用%它挤压到一个孩子的View大小。我甚至尝试了flex:1alignSelf:stretchalignItem:stretchwidth:'100%'等,但没有运气。
有一阵子,我们来谈谈中间那排(附图片)它包含3列。2我想要左和右块(菜单和行动号召)每个都是300 px。现在,如果我在1000 px宽度的显示器上,我的内容块应该是(1000 -(300+300))400 px。如果显示器为1200 px,则内容块将为(1200 -(300+300))600 px。

t8e9dugd

t8e9dugd1#

我希望这不会来得太晚。

<View style={{ flex: 1 }}>
    <View style={{ height: 100, backgroundColor: 'red' }} />

    <View style={{ flex: 1, backgroundColor: 'gray', flexDirection: 'row' }}>
      <View style={{ width: 100, backgroundColor: 'green' }} />
      <View style={{ flex: 1, backgroundColor: 'blue' }} />
      <View style={{ width: 100, backgroundColor: 'green' }} />
    </View>

    <View style={{ height: 100, backgroundColor: 'red' }} />
  </View>

这是上面代码的结果。

您根本不需要进行百分比计算;只需将其结构化为2层Flex布局即可。
对于不应拉伸的组件,说明其宽度。对于其余组件,指定弹性值。
如果您坚持使用1层来处理所有问题,那么我们将再次讨论。
干杯干杯干杯

hgncfbus

hgncfbus2#

我做这个完全出于同样的原因:
https://www.npmjs.com/package/react-native-animated-layout

它将布局作为输入,并使用屏幕的宽度/高度比来决定要使用的布局。
在每个布局中,使用0和1之间的坐标定义每个屏幕的上、右、下、左。(因为浏览器调整大小会更改每个视图的坐标,而您希望视图保持精确的相对位置。)

import React, { useState, useEffect } from 'react';
import { Text, View } from 'react-native';
import ReactNativeAnimatedLayout from 'react-native-animated-layout';

export default function App() {
    const [rerender, setRerender] = useState(0);
    const redView = <View style={{ backgroundColor: 'red', height: '100%', width: '100%', }}><Text>{"I am the red view"}</Text></View>;
    const greenView = <View style={{ backgroundColor: 'green', height: '100%', width: '100%', overflow: 'hidden'}}>
        <Text>{"I am the green view and my contents overflow. Because of the overflow prop, the over-flown content is hidden."}</Text><Text>{"0"}</Text><Text>{"1"}</Text><Text>{"2"}</Text><Text>{"3"}</Text><Text>{"4"}</Text><Text>{"5"}</Text><Text>{"6"}</Text><Text>{"7"}</Text><Text>{"8"}</Text><Text>{"9"}</Text><Text>{"10"}</Text><Text>{"11"}</Text><Text>{"12"}</Text><Text>{"13"}</Text><Text>{"14"}</Text><Text>{"15"}</Text><Text>{"16"}</Text><Text>{"17"}</Text><Text>{"18"}</Text><Text>{"19"}</Text><Text>{"20"}</Text><Text>{"21"}</Text><Text>{"22"}</Text><Text>{"23"}</Text><Text>{"24"}</Text><Text>{"25"}</Text><Text>{"26"}</Text><Text>{"27"}</Text><Text>{"28"}</Text><Text>{"29"}</Text>
        </View>;
    const blueView = <View style={{ backgroundColor: 'blue', height: '100%', width: '100%', }}><Text>{"I am the blue view"}</Text></View>;
    const layouts = [
        {
            validAfterWHRatio: 0,
            validBeforeWHRatio: 0.9,
            views: [
                { top: 0, bottom: 0.5, left: 0, right: 1, children: redView },
                { top: 0.75, bottom: 1, left: 0, right: 1, children: blueView },
                { top: 0.5, bottom: 0.75, left: 0, right: 1, children: greenView },
            ]
        },
        {
            validAfterWHRatio: 1 / 0.62,
            validBeforeWHRatio: 999, // infinity
            views: [
                { top: 0, bottom: 1, left: 0, right: 0.5, children: redView },
                { top: 0.5, bottom: 1, left: 0.5, right: 1, children: blueView },
                { top: 0, bottom: 0.5, left: 0.5, right: 1, children: greenView },
            ]
        },
        {
            defaultFlag: true,
            views: [
                { top: 0.16, bottom: 0.84, left: 0.16, right: 0.5, children: redView },
                { top: 0.50, bottom: 0.84, left: 0.5, right: 0.84, children: blueView },
                { top: 0.16, bottom: 0.50, left: 0.5, right: 0.84, children: greenView },
            ]
        },
    ];

    useEffect(() => {
        let nextRerender = rerender + 1;
        setRerender(nextRerender);
    }, []); // when we want to re-render

    return <ReactNativeAnimatedLayout
        layouts={layouts}
        rerender={rerender}
    />;
}

注意:此方法对PWA尤其有用。如果需要使用滚动条,它们应位于其中一个视图(可能是"内容"视图)内。

相关问题