I've designed a layout for my React Native application that includes several components. Among these are a header, a FlatList that displays dates horizontally, and a gray View containing various components related to activities. However, I'm encountering an issue where there's a significant amount of white space between the FlatList and the gray View. My objective is to minimize this white space and bring the gray View closer to the FlatList, ensuring a more visually appealing layout. And the last problem is with the 2 cards you can see that are not aligned correctly.
import React, { useState } from "react";
import {
FlatList,
Dimensions,
Alert,
TouchableOpacity,
Image,
View,
StyleSheet,
} from "react-native";
import { Text, Button, Icon } from "@rneui/base";
import { SafeAreaView } from "react-native-safe-area-context";
import OrarioCheckIn from "@/OrarioCheckIn";
import OrarioCheckOut from "@/OrarioCheckOut";
import UserCheckIn from "@/UserCheckIn";
import UserCheckOut from "@/UserCheckOut";
import { ScrollView } from "react-native-gesture-handler";
const { width } = Dimensions.get("window");
const daysToShow = 4;
const margin = 10;
const itemWidth = (width - margin * (daysToShow * 2)) / daysToShow;
const totalDays = 30;
export default function Home() {
const today = new Date();
const currentDate = today.toLocaleDateString("it-IT", {
weekday: "short",
day: "2-digit",
month: "short",
});
const formatTime = (time: number) => {
return time < 10 ? `0${time}` : `${time}`;
};
const currentTime = `${formatTime(today.getHours())}:${formatTime(
today.getMinutes()
)}`;
const dates = Array.from({ length: totalDays }, (_, i) => {
const d = new Date();
d.setDate(today.getDate() - i);
return d;
}).reverse();
const getItemLayout = (data: any, index: number) => ({
length: itemWidth + margin * 2,
offset: (itemWidth + margin * 2) * index,
index,
});
const capitalizeFirstLetter = (string: string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
const [showCheckIn, setShowCheckIn] = useState(false);
const [showCheckOut, setShowCheckOut] = useState(false);
const [checkInTime, setCheckInTime] = useState(currentTime);
const [checkOutTime, setCheckOutTime] = useState("");
const handleCheckInClick = () => {
const now = new Date();
const currentCheckInTime = `${formatTime(now.getHours())}:${formatTime(
now.getMinutes()
)}`;
setCheckInTime(currentCheckInTime);
setShowCheckIn(true);
setShowCheckOut(false);
};
const handleCheckOutClick = () => {
const now = new Date();
const currentCheckOutTime = `${formatTime(now.getHours())}:${formatTime(
now.getMinutes()
)}`;
setCheckOutTime(currentCheckOutTime);
setShowCheckOut(true);
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<TouchableOpacity
onPress={() => Alert.alert("Profile button pressed")}
>
<Image
source={{
uri: "https://cdn-icons-png.flaticon.com/512/0/14.png",
}}
style={styles.profileImage}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={() => Alert.alert("Notification button pressed")}
>
<Icon
name="notifications"
color="black"
style={styles.notificationIcon}
/>
</TouchableOpacity>
</View>
<FlatList
style={styles.flatList}
contentContainerStyle={styles.flatListContent}
data={dates}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
renderItem={({ item: date }) => (
<TouchableOpacity
onPress={() =>
Alert.alert(
`Hai selezionato il giorno ${date.getDate()}`
)
}
style={styles.dateItem}
>
<Text style={styles.dateNumber}>{date.getDate()}</Text>
<Text style={styles.dateWeekday}>
{capitalizeFirstLetter(
date.toLocaleDateString("it-IT", {
weekday: "short",
})
)}
</Text>
</TouchableOpacity>
)}
keyExtractor={(item, index) => index.toString()}
initialScrollIndex={totalDays - daysToShow}
getItemLayout={getItemLayout}
/>
<View style={styles.wrapper}>
<View style={styles.contentWrapper}>
<View style={styles.activityContainer}>
<Text style={styles.heading}>Oggi</Text>
<View style={styles.activityRow}>
<OrarioCheckIn />
<OrarioCheckOut />
</View>
</View>
<Text style={styles.heading}>Le tue attività </Text>
<View style={styles.userActivitiesContainer}>
<ScrollView style={styles.userActivities}>
{showCheckIn && (
<UserCheckIn
orario={checkInTime}
data={currentDate}
/>
)}
{showCheckOut && (
<UserCheckOut
orario={checkOutTime}
data={currentDate}
/>
)}
{!showCheckIn && !showCheckOut && (
<Text style={styles.noActivityText}>
Non hai effettuato il check-in o il
check-out
</Text>
)}
</ScrollView>
</View>
<Button
title={
showCheckIn
? "Scorri per il Check Out"
: "Scorri per il Check In"
}
radius="lg"
buttonStyle={styles.actionButton}
titleStyle={styles.actionButtonText}
onPress={
showCheckIn
? handleCheckOutClick
: handleCheckInClick
}
/>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
},
header: {
flexDirection: "row",
justifyContent: "space-between",
padding: 15,
},
profileImage: {
width: 50,
height: 50,
borderRadius: 25,
},
notificationIcon: {
fontSize: 24,
},
wrapper: {
flex: 1,
backgroundColor: "#F9F9F9",
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
paddingTop: 20,
},
flatList: {
marginBottom: 10,
},
flatListContent: {
paddingBottom: 20,
},
dateItem: {
width: itemWidth,
height: 80,
borderWidth: 1,
borderColor: "lightgrey",
backgroundColor: "white",
justifyContent: "center",
alignItems: "center",
margin: margin,
borderRadius: 10,
},
dateNumber: {
fontFamily: "KumbhSans-Bold",
fontSize: 24,
},
dateWeekday: {
fontFamily: "KumbhSans-Regular",
fontSize: 16,
},
contentWrapper: {
paddingHorizontal: 10,
flex: 1,
},
activityContainer: {
flexDirection: "row",
justifyContent: "space-between",
padding: 15,
},
heading: {
fontFamily: "KumbhSans-Bold",
fontSize: 20,
marginLeft: 15,
marginBottom: 10,
},
activityRow: {
flexDirection: "row",
},
userActivitiesContainer: {
flex: 1,
marginBottom: 10,
},
userActivities: {
flex: 1,
},
noActivityText: {
textAlign: "center",
fontFamily: "KumbhSans-Bold",
color: "gray",
fontSize: 15,
marginTop: 10,
},
actionButton: {
height: 50,
backgroundColor: "#3B82F6",
marginBottom: 20,
marginHorizontal: 20,
},
actionButtonText: {
fontFamily: "KumbhSans-Regular",
fontSize: 20,
},
});
If needed I will provide the components code. Thanks.
In your styles code you have:
wrapper: {
flex: 1,
backgroundColor: "#F9F9F9",
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
paddingTop: 20,
},
flatList: {
marginBottom: 10,
},
flatListContent: {
paddingBottom: 20,
},
So what happens here is your flatList
has paddingBottom
of 20px and marginBottom
set to 10px. Also you set paddingTop
of your wrapper
to 20px, so in total you have 50px of white space. Plese try to lower these values to reduce the white space between flatList
and wrapper
.