Home > Enterprise >  React native SafeAreaView going under navigation header
React native SafeAreaView going under navigation header

Time:02-17

As you can see in the image below, I have to give some top margin in order to "not" hide my half of the content under the navigation header, isn't header supposed to be a "safe area" for the below content, to be on the safe side I provided the SafeAreaView but still my content goes under the Header and unfortunately I have to give some hardcoded margin top value to avoid hiding.

The above image is when I comment marginTop.

enter image description here

Above image is when I add marginTop: 70

Code:

NotificationScreen.tsx:

import {
  View,
  SafeAreaView,
  Text,
  StatusBar,
} from 'react-native';
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated';
import OrderItem from '../../components/OrderItem';

const NotificationScreen = () => {
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    // calling API...
  }, []);

  return (
    <SafeAreaView style={styles.container}>
      <StatusBar backgroundColor="transparent" translucent />

      <Text style={{color: 'lightgray', fontSize: 18}}>My Orders: </Text>

      <Animated.FlatList
        data={orders}
        entering={FadeIn}
        leaving={FadeOut}
        contentContainerStyle={{
          alignItems: 'center',
        }}
        keyExtractor={(_: any, index) => 'key'   index}
        renderItem={({item}) => <OrderItem key={item.id} data={item} />}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    marginTop: 70, // if I remove this, the content goes under the header as shown in image.
    flex: 1,
    padding: 10,
    backgroundColor: COLORS.primary,
  },
});

export default NotificationScreen;

One more query, why my OrderItem not taking the full width of FlatList (see image, the gray box is not takin the full width...), I have provided width: 100% to my OrderItem container:

OrderItem.tsx:

const OrderItem = ({data}) => {
  return (
    <View style={styles.container}>
      <View style={styles.textBlock}>
        <Text style={styles.label}>Strategy: </Text>
        <Text style={styles.info}>{data.strategyTitle}</Text>
      </View>
      // ... same views as shown in image
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    width: '100%',
    paddingVertical: 10,
    paddingHorizontal: 10,
    alignItems: 'center',
    justifyContent: 'space-between',
    backgroundColor: COLORS.lightGray,
    borderRadius: 10,
  },
  textBlock: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  label: {
    color: 'grey',
    fontSize: 16,
  },
  info: {
    color: 'white',
    fontSize: 16,
  },
});

export default OrderItem;

CodePudding user response:

The SafeAreaView does not work currently for Android devices. You need to have something like this to avoid this issue:

import { Platform,StatusBar } from "react-native";
const styles = StyleSheet.create({
  container: {
    paddingTop: Platform.OS == "android" ? StatusBar.currentHeight : 0,
  },
});
 <SafeAreaView style={styles.container}>
   
</SafeAreaView>

And for the OrderItem not taking all available width, remove from Animated.FlatList this:

contentContainerStyle={{alignItems: 'center'}}

CodePudding user response:

I found a solution, but I'm not sure whether it will work for all screen sizes or not, here it is:

I used a hook provided by @react-navigation/elements, -> useHeaderHeight.

import {useHeaderHeight} from '@react-navigation/elements';

return ...

<SafeAreaView style={[styles.container, {paddingTop: headerHeight}]}>
      <StatusBar backgroundColor="transparent" translucent />

      <Text style={{color: 'lightgray', fontSize: 18}}>My Orders: </Text>

      <Animated.FlatList
        data={orders}
        entering={FadeIn}
        leaving={FadeOut}
        contentContainerStyle={{
          alignItems: 'center',
          // backgroundColor: COLORS.red,
        }}
        keyExtractor={(_: any, index) => 'key'   index}
        renderItem={({item}) => <OrderItem key={item.id} data={item} />}
      />
</SafeAreaView>

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
    backgroundColor: COLORS.primary,
  },
});

This is working, but still coming to my 2nd query as mentioned in the question, the OrderItem is not taking the full width of my flatlist... Can someone help me with that? Thanks!

  • Related