React Native SafeAreaView background color - Как назначить два разных цвета фона для верхней и нижней части экрана?

Я использую SafeAreaView от React Native 0.50.1, и он работает неплохо, за исключением одной части. Я назначил оранжевый цвет фона SafrAreaView, но не могу понять, чтобы изменить нижний небезопасный фон области на черный.

Вот код, и я включил ожидаемый результат и фактический результат. Каков наилучший способ сделать нижнюю часть экрана черной, а не оранжевой?

import {
  ...
  SafeAreaView
} from 'react-native';
class Main extends React.Component {
  render() {
    return (
      <SafeAreaView style={styles.safeArea}>
        <App />
      </SafeAreaView>
    )
  }
}
const styles = StyleSheet.create({
  ...,
  safeArea: {
    flex: 1,
    backgroundColor: '#FF5236'
  }
})

Ответ 1

Я смог решить эту проблему, используя версию ответов Йошики и Зака Шнайдера. Обратите внимание, как вы устанавливаете верхний SafeAreaView flex:0 чтобы он не расширялся.

render() {
  return (
    <Fragment>
      <SafeAreaView style={{ flex:0, backgroundColor: 'red' }} />
      <SafeAreaView style={{ flex:1, backgroundColor: 'gray' }}>
        <View style={{ flex: 1, backgroundColor: 'white' }} />
      </SafeAreaView>
    </Fragment>
  );
}

enter image description here

Ответ 2

Я смог решить эту проблему, используя хакерство абсолютной позиции. См. Следующую настройку. Не будущее доказательство каким-либо образом, но оно решает проблему, которую я имел.

import {
  ...
  SafeAreaView,
  View
} from 'react-native';
class Main extends React.Component {
  render() {
    return (
      <SafeAreaView style={styles.safeArea}>
        <App />
        <View style={styles.fixBackground} />
      </SafeAreaView>
    )
  }
}
const styles = StyleSheet.create({
  ...,
  safeArea: {
    flex: 1,
    backgroundColor: '#FF5236'
  },
  fixBackground: {
    backgroundColor: 'orange',
    position: 'absolute',
    bottom: 0,
    right: 0,
    left: 0,
    height: 100,
    zIndex: -1000,
  }
})

Ответ 3

Я столкнулся с той же проблемой и смог решить следующее:

const styles = StyleSheet.create({
  outerWrapper: {
    backgroundColor: 'orange',
  },
  innerWrapper: {
    backgroundColor: 'black',
  },
});

// snip

const MyComponent = ({ content }) => (
  <View style={styles.outerWrapper}>
    <SafeAreaView />

    <SafeAreaView style={styles.innerWrapper}>
      {content}
    </SafeAreaView>
  </View>
);

outerWrapper применяет оранжевый цвет фона вверху. Первый <SafeAreaView/> толкает второй вниз, чтобы он начинался в начале "безопасной области" (ниже строки состояния). Затем второй SafeAreaView занимает остальную часть экрана (включая нижнюю "небезопасную" область) и присваивает ему черный фоновый цвет.

Ответ 4

Вы можете вернуть несколько SafeAreaView из вашего метода рендеринга, используя Fragment, каждый из которых независимо указывает свой backgroundColor:

render = () => (
  <Fragment>
    <SafeAreaView style={{ flex: 0.5, backgroundColor: "red" }} />
    <SafeAreaView style={{ flex: 0.5, backgroundColor: "blue" }} />
  </Fragment>
);

Результат на iPhone X:

enter image description here

Ответ 5

  • Может быть, полезно, я попробовал решение для этого запроса, но ниже подхода был лучшим в моем случае.
  • Несколько видов/контейнеров имели фоновое изображение.

  • В моем случае я решил использовать размер экрана iPhone x.

  • Приложение предназначено только для портретного режима.
  • Обнаружено устройство, а для iPhone X только что настроено верхнее и нижнее элементы.

  • Этот подход помог сохранить тему приложения и использовать полный экран iPhone X.

    isIPhoneX = () => {
            const X_HEIGHT = 812, X_WIDTH = 375;
            const {"height": D_HEIGHT, "width": D_WIDTH} = Dimensions.get("window");
    
            return Platform.OS === "ios" &&
              (D_HEIGHT === X_HEIGHT && D_WIDTH === X_WIDTH ||
                D_HEIGHT === X_WIDTH && D_WIDTH === X_HEIGHT);
    
        }
    

Ответ 6

Я смог добиться этого с помощью кода ниже,

<View style={{
    flex: 1
}}>
  <SafeAreaView style={{
    flex: 0,
    backgroundColor: 'red'
  }}>
  </SafeAreaView>
  <View style={{
      flex: 1,
      top: 0,
      backgroundColor: 'white'
   }}>
  </View></View>

Спасибо за @Daniel M, вдохновленный его ответом.

Ответ 7

Я только что столкнулся с той же проблемой, у нас есть панель навигации вверху и панель вкладок внизу с двумя разными цветами фона.

Мое решение состояло в том, чтобы обернуть компонент панели вкладок в SafeAreaView с правильным цветом фона, а также обернуть компонент панели навигации своим собственным SafeAreaView с его цветом фона.

return (
  <SafeAreaView style={{ backgroundColor: 'white' }}>
    <Animated.View style={heightAnim}>
      {...navBarComponentStuff}
    </Animated.View>
  </SafeAreaView>)

Для панели навигации

И это для панели вкладок:

<SafeAreaView style={this.props.tabBarStyle}> //Some dark grey color is passed here
  <Animated.View style={heightAnim}>
    {tabBarItems.map(render tabs.....}
  </Animated.View>
</SafeAreaView>}

Таким образом, можно сказать, что вы можете обернуть свой навигационный компонент в SafeAreaView с оранжевым цветом, установленным в стиле, и обернуть основное содержимое в другой SafeAreaView с черным в качестве стиля backgroundColor или любого другого цвета, который вы выбрали.

Одна вещь, которую вы должны знать, если вы добавите два SafeAreaView в один и тот же компонент, например:

return (
  <View style={styles.container}>
    <SafeAreaView style={{ backgroundColor: 'white' }}>
      <NavigationBarComponent />
    </SafeAreaView>
    <SafeAreaView style={this.props.tabBarStyle}>
      <Animated.View style={heightAnim}>
        <Animated.View style={[styles.tabBar, this.props.tabBarStyle]}>
          {map and render tabs}
        </Animated.View>
      </Animated.View>
    </SafeAreaView>
  </View>
);

Он объединит два SafeAreaView или, по крайней мере, так мне показалось, может быть, кто-то с большим опытом в этом может объяснить, что происходит в этой ситуации.

Это подтолкнуло мою панель вкладок к верхней части экрана и установило белый цвет фона, когда я это сделал.

Но перемещение верхнего SafeAreaVeiw в NavigationBarComponent дало мне желаемый эффект.

Для тех, кому это может быть интересно, и, возможно, это и является причиной того, что с двумя из них в одном и том же представлении он работает так же, как AnimatedView, потому что мы иногда скрываем панели навигации и вкладки.