Верхняя панель навигации React получает одинаковую высоту (НЕ) в зависимости от ее собственных компонентов

Глядя на этот пример с веб-сайта React Navigation, между чатом и контактами, высоты не зависят друг от друга. Однако, когда я попытался реализовать верхнюю планку, высота была такой же. Требуется высота, на которой вкладка имеет наибольшее количество содержимого.

Но в этом примере вы можете видеть в разделе «Контакты», что может быть больше контактов, которые можно прокручивать, а в чате поле ввода находится внизу, что делает его похожим на то, на чем оно заканчивается.

Вот скриншот из примера:

Вкладка чата

введите описание изображения здесь

Вкладка "Контакты"

введите описание изображения здесь

Вот часть моего кода и то, что я испытываю:

<View style={{backgroundColor: 'orange'}}>
  {!loading &&
    !loadingProfileInfo &&
    typeof data.infoByUser !== 'undefined' && (
      <FlatList
        data={data.infoByUser}
        ListHeaderComponent={
          <View>
            <UserInfo />

            <Tab.Navigator>
              <Tab.Screen 
                name="Test" 
                component={TestComponent} />
              <Tab.Screen
                name="New Tab"
                component={NewTabComponent}
              />
            </Tab.Navigator>
          </View>
        }
        numColumns={2}
        renderItem={({item}) => (
          <View>
           // ...
          </View>
        )}
        keyExtractor={item => item._id}
      />
    )}
</View>

TestComponent

<View style={{backgroundColor: 'grey'}}>
  <View>
    <Text>Test Test</Text>
  </View>
  <View>
    <Text>Test Test</Text>
  </View>
  <View>
    <Text>Test Test</Text>
  </View>
  <View>
    <Text>Test Test</Text>
  </View>
  <View>
    <Text>Test Test</Text>
  </View>
</View>

NewTabComponent

<View style={{backgroundColor: 'red'}}>
  <Text>new tab</Text>
</View>

введите описание изображения здесь  введите описание изображения здесь

Обратите внимание на то, что на новой вкладке есть большой промежуток между красным и оранжевым, это от высоты вкладки «Тест».


comment
поделитесь пожалуйста скриншотом.   -  person Vikas chhabra    schedule 15.04.2020
comment
Вы визуализируете вкладки внутри ScrollView?   -  person Ashwin Mothilal    schedule 15.04.2020
comment
Можете показать скриншот?   -  person Anhdevit    schedule 15.04.2020
comment
@Vikaschhabra Я добавил снимок экрана, пожалуйста, посмотрите, когда сможете.   -  person hellomello    schedule 16.04.2020
comment
@AshwinMothilal Я добавил снимок экрана. Я визуализирую его внутри заголовка FlatList   -  person hellomello    schedule 16.04.2020
comment
@AnhDevit отредактировал мой вопрос со снимком экрана, спасибо, ребята!   -  person hellomello    schedule 16.04.2020
comment
@hellomello Вы ее решили?   -  person Idan    schedule 30.07.2020
comment
@ Идана еще нет :(   -  person hellomello    schedule 30.07.2020


Ответы (4)


Вы визуализируете весь свой навигатор как заголовок FlatList. Вы даже не должны использовать Flatlist в этом компоненте. На каждом экране разное количество элементов и должен быть собственный плоский список.

Чтобы исправить это:

  • Удалите FlatList из вашего основного компонента (с backgroundColor: 'orange') и просто визуализируйте Tab Navigator в этой функции рендеринга.

  • Внутри TestComponent и NewTabComponent визуализируйте ScrollView (или FlatList), если он вам нужен.

  • Все экраны (TestComponent и NewTabComponent) должны иметь height: '100%' или flex: 1, если вы хотите, чтобы все экраны занимали все пространство экрана, даже если его реальная высота меньше высоты экрана.

person Ben Butterworth    schedule 15.04.2020
comment
Я добавил снимок экрана и код, вы можете видеть, что высота моих вкладок не зависит от содержимого. - person hellomello; 16.04.2020
comment
Если у TestComponent и NewTabeComponent есть своя собственная прокрутка, как мне прокрутить основной компонент? В моем основном компоненте у меня есть информация о пользователе вверху (аналогично разделу профиля в Instagram), как мне с этим прокрутить? Эти вкладки находятся под разделом информации о пользователе. - person hellomello; 18.04.2020
comment
Если вы хотите, чтобы ваша «информация о пользователе» прокручивалась, она также должна находиться в том же ScrollView. Есть ли причина, по которой вы хотите оставить его за пределами Scrollview? Вы показываете информацию о пользователе на обеих вкладках? Это руководство может оказаться полезным. - person Ben Butterworth; 18.04.2020
comment
Спасибо за ссылку на руководство. Похоже, он даже не использует плоский список или какую-либо прокрутку, даже не уверен, как он может просматривать, возможно, мне нужно посмотреть все его уроки. Но причина, по которой я выбрал плоский список, заключается в производительности. Насколько я понимаю, именно поэтому был создан плоский список? Кроме того, он не использует встроенные вкладки навигации, возможно, его метод простой проверки того, какую вкладку нужно щелкнуть, является предпочтительным методом? - person hellomello; 18.04.2020
comment
Я не вижу способа разместить что-то за пределами createMaterialTopTabNavigator на том же экране. Я думаю, почему некоторые учебные пособия по YouTube идут с менее распространенными библиотеками, потому что вам нужна гибкость. - person Ben Butterworth; 18.04.2020
comment
Вы сделали это? Некоторое время назад я попытался обработать этот flexbox равной высоты, непосредственно касаясь компонента viene rn tab. - person Victor Molina; 28.11.2020

Я понятия не имею, почему вы его рендерируете внутри FlatList, поскольку он также наследует свойства от Scroll View.

<View style={{backgroundColor: 'orange'}}>
  <Tab.Navigator>
      <Tab.Screen 
        name="Test" 
        component={TestComponent} />
      <Tab.Screen
        name="New Tab"
        component={NewTabComponent}
      />
  </Tab.Navigator>
</View>

и переместите FlatList и другую бизнес-логику внутрь TestComponent или NewTabComponent.

Дело в том, что не отображайте вкладки внутри ScrollView, FlatList или SectionList, поскольку они оба наследуют свойства ScrollView.

person Ashwin Mothilal    schedule 16.04.2020
comment
Я сделал это так, потому что мне нужен был какой-то заголовок, например, как работает страница профиля в Instagram. Поэтому, когда вы прокручиваете, вкладки будут прокручиваться с информацией профиля, которая находится в верхней части экрана. - person hellomello; 17.04.2020
comment
@hellomello У меня точно такая же проблема, вы это исправили? Я думаю, это из-за того, что вкладка заключена в нижний колонтитул FlatList. - person Victor Molina; 27.08.2020

После долгого исследования я обнаружил, что ваша проблема в том, что в response-native-tab-view (который используется material-tob-tabs) есть следующий код:

_defineProperty(this, "handleLayout", e => {
  const {
    height,
    width
  } = e.nativeEvent.layout;

  if (this.state.layout.width === width && this.state.layout.height === height) {
    return;
  }

  this.setState({
    layout: {
      height,
      width
    }
  });

С опцией lazy = {true} и с помощью компонента «Новая вкладка» на первой вкладке и «Тест» на второй вы получите нужную высоту до тех пор, пока не измените вкладку. Когда вы нажимаете «Тест», макет изменяется, поэтому высота увеличивается. После изменения вкладки высота больше не меняется, потому что макет остается прежним («Новая вкладка» идеально подходит для большей высоты) и не запускает handleLayout из response-native-tab-view.

Надеюсь, вы сможете найти способ снова изменить макет при смене вкладок.

person CevaComic    schedule 21.04.2020

Чтобы иметь высоту в соответствии с содержимым внутри конкретной вкладки, используйте Scrollview внутри каждой вкладки. Поблагодарите меня позже, если это сработает идеально. :)

import * as React from "react";
import { ScrollView, Text, View } from "react-native";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";

function Screen1() {
  return (
    <ScrollView>
      <View style={{ flex: 1, alignItems: "center" }}>
        <Text style={{ padding: 10 }}>Screen1 </Text>
      </View>
    </ScrollView>
  );
}

function Screen2() {
  return (
    <ScrollView>
      <View style={{ flex: 1, alignItems: "center" }}>
        <Text style={{ padding: 10 }}>Screen2</Text>
      </View>
    </ScrollView>
  );
}

function Screen3() {
  return (
    <ScrollView>
      <View style={{ flex: 1, alignItems: "center" }}>
        <Text style={{ padding: 10 }}>Screen3 </Text>
      </View>
    </ScrollView>
  );
}

const Tab = createMaterialTopTabNavigator();

export default function TopBarNavigator() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Screen1" component={Screen1} />
      <Tab.Screen name="Screen2" component={Screen2} />
      <Tab.Screen name="Screen3" component={Screen3} />
    </Tab.Navigator>
  );
}
person anoNewb    schedule 07.07.2021