Expo is adding padding to top and bottom weirdly. I don't even use SafeAreaView or useSafeAreaInsets etc.
I tried to wrap layout with View, SafeAreaProvider, SafeAreaContext with setting bgColor and flex:1 none of them worked. I inspected with React Devtools and i guess expo auto add SafeAreaProvider?
(I'm using expo router and don't use any ui library)
_layout.tsx:
<Tabs
safeAreaInsets={{ top: 0, right: 0, bottom: 0, left: 0 }}
screenOptions={{
headerStatusBarHeight: 0,
headerShown: false,
tabBarStyle: {
backgroundColor: Colors.primarySoft,
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
height: 25 + insets.bottom,
paddingBottom: 0,
},
headerPressColor: Colors.orange,
tabBarActiveTintColor: Colors.orange,
tabBarInactiveTintColor: Colors.grey,
tabBarLabelStyle: {
fontFamily: Fonts.bold,
fontSize: 12,
},
}}
>
<Tabs.Screen
name="index"
options={{
title: "Home",
tabBarIcon: ({ focused, color }) => (
<Ionicons
name={"home"}
size={24}
color={color}
/>
),
}}
/>
<Tabs.Screen
name="leaderboard"
options={{
title: "Leaderboard",
tabBarIcon: ({ focused, color }) => (
<Ionicons
name={"trophy"}
size={24}
color={color}
/>
),
}}
/>
<Tabs.Screen
name="achievements"
options={{
title: "Achievements",
tabBarIcon: ({ focused, color }) => (
<Ionicons
name={"medal"}
size={24}
color={color}
/>
),
}}
/>
<Tabs.Screen
name="profile"
options={{
title: "Profile",
tabBarIcon: ({ focused, color }) => (
<Ionicons
name={"person"}
size={24}
color={color}
/>
),
}}
/>
</Tabs>
index.tsx:
export default function HomeScreen() {
const [selectedFriend, setSelectedFriend] = useState("1");
return (
<View style={styles.safeArea}>
<ScrollView
style={styles.container}
contentContainerStyle={styles.scrollContent}
>
{/* user info */}
<View style={styles.userContainer}>
<CustomText variant="bold" style={styles.welcomeText}>
Welcome back,{" "}Selçuk
</CustomText>
</View>
{/* start play */}
<View style={styles.startPlayContainer}>
<View>
<CustomText variant="bold" style={styles.startPlayText}>
Start playing {"\n"}quiz now
</CustomText>
<TouchableOpacity onPress={()=>router.push("/game/create")} style={styles.startPlayButton}>
<CustomText style={styles.startPlayButtonText}>Start</CustomText>
</TouchableOpacity>
</View>
<Image
style={styles.startPlayImage}
resizeMode="cover"
source={require("@/assets/images/home/3d_illustration_nature.png")}
/>
</View>
{/* friends */}
<FriendList
friends={friends}
selectedFriend={selectedFriend}
onSelectFriend={setSelectedFriend}
/>
{/* discovery */}
<Discovery />
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingHorizontal: 16,
},
safeArea: {
flex: 1,
backgroundColor: Colors.primary,
},
userContainer: {
marginTop: 4,
},
welcomeText: {
fontSize: 24,
fontWeight: "500",
color: Colors.black,
},
startPlayContainer: {
flexDirection: "row",
marginTop: 30,
position: "relative",
alignItems: "center",
justifyContent: "space-between",
gap: 8,
backgroundColor: Colors.green,
paddingHorizontal: 25,
paddingVertical: 30,
borderRadius: 16,
},
startPlayText: {
fontSize: 18,
fontWeight: "500",
color: Colors.white,
},
startPlayImage: {
width: 200,
height: 200,
position: "absolute",
top: -20,
right: 0,
},
startPlayButton: {
borderWidth: 1,
borderColor: Colors.white,
padding: 5,
borderRadius: 15,
marginTop: 10,
},
startPlayButtonText: {
fontSize: 14,
fontWeight: "500",
color: Colors.white,
textAlign: "center",
},
scrollContent: {
paddingBottom: 25,
},
});
Added _layout.tsx to my app folder root. And below code.
<Stack screenOptions={{ headerShown: false }} />
this fixed my issue.