在 React Native 中禁用 Flexbox 等高列

Vic*_*ina 5 javascript css flexbox reactjs react-native

澄清

目前我正在使用这个包https://github.com/satya164/react-native-tab-view,但我也尝试过这个来自反应导航https://reactnavigation.org/docs/material-top-tab -navigator/并有同样的问题。

基本上我试图删除默认的 flexbox 行为“等高列”

介绍

我正在实现一个具有三个场景的选项卡视图。第一个将是一个带有无尽和分页平面列表的屏幕(其高度未确定),其他两个有自己的视图,高度确定。

问题

当第一个标签的内容被渲染时,它的高度是好的,但是当另一个标签被渲染并且它的高度大于第一个时,它(第一个标签)将其高度更改为另一个标签的高度。

第一个选项卡可以有 +100000 个项目,但假设目前它只有 1 个大小为 30px 的项目。第二个选项卡的高度不可变,为 40 像素,最后一个为 50 像素。

使用我当前的代码,会发生以下情况:

紫色空间不应该出现

紫色空间不应该出现!!

代码

由于代码较长,我在相关部分注释了“<--------”。

export default function Tab(props) {
  const [index, setIndex] = useState(0);
  const [tab1Height, setTab1Height] = useState(null);
  const [tab2Height, setTab2Height] = useState(null);


  const [routes] = useState([
    { key: "tab0", title: "Tab0" },
    { key: "tab1", title: "Tab1" },
    { key: "tab2", title: "Tab2" },
  ]);

  const handleTabHeights = (height, tabIndex) => { // <--------
     // Do nothing if no height
     if (height <= 0) return;

     switch (tabIndex) {
       case 1:
         setTab1Height(height);
         return;
       case 2:
         setTab2Height(height);
         return;
       default:
         return;
     }
   };

 const renderScene = ({ route }) => { // <--------
    switch (route.key) {
      case "tab0":
        return <EndlessScreen {...this.props} />; // <---- Not handling the scene height because it is undetermined (can be 0, 1000, 30, 9000... any value, and can change in some item is added to the flatlist)
      case "tab1":
        return (
          <View
            onLayout={(event) => // <-------
              handleTabHeights(event.nativeEvent.layout.height, 1)
            }
          >
            <View style={{ height: 40, backgroundColor: "lime" }} {...this.props} />
          </View>
        );
      case "tab2":
        return (
          <View
            onLayout={(event) => // <---------
              handleTabHeights(event.nativeEvent.layout.height, 2)
            }
          >
             <View style={{ height: 50, backgroundColor: "red" }} {...this.props} />
          </View>
        );
      default:
        return null;
    }
  };

 // ... other stuff

 return (
    <TabView
      style={ // <-----------
        index === 0
          ? { flex: 1, backgroundColor: "purple" } <--------- THINKS THAT HERE IS THE PROBLEM
          : {
              height: index === 1 ? tab1Height : tab2Height,
            }
      }
      renderTabBar={renderTabBar}
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
      removeClippedSubviews={false} // Pd: Don't enable this on iOS where this is buggy and views don't re-appear.
      swipeEnabled={true}
      lazy={false}
    />
  );
Run Code Online (Sandbox Code Playgroud)

我认为问题是什么

我认为我必须使用 onLayout 和更新状态来动态地获取平面列表的高度,但这会导致多个状态更新,并且会对性能产生很大影响。必须有其他方法来处理这个问题,我的意思是,一些 css 或 flex 属性(或其他东西)使第一个选项卡将其高度正确地调整到它的平面列表。

观察

如果第一个标签具有最大的高度,则一切都很完美,所有标签都有各自的高度。

我试过的

我试图动态地获得 FlatList 的高度,但这太困难了,因为 useState 是异步的,并且当用户向平面列表添加或删除一项时不会调用 onLayout 道具......

有任何想法吗?我将衷心感谢您的帮助。