Commit 96d19d3b by nguyenquangtung004

TODO: Đã fix thành công SafeAreaView không bị khoảng trắng trên màn hình home

parent 61052ad2
import React from 'react'; import React from 'react';
import { import {
SafeAreaView,
StyleSheet, StyleSheet,
Text, Text,
TouchableOpacity, TouchableOpacity,
......
...@@ -49,7 +49,6 @@ const styles = StyleSheet.create({ ...@@ -49,7 +49,6 @@ const styles = StyleSheet.create({
container: { container: {
flexDirection: "row", flexDirection: "row",
marginHorizontal: 15, marginHorizontal: 15,
marginTop: 15,
maxHeight: 40, maxHeight: 40,
}, },
size_box:{ size_box:{
......
...@@ -10,6 +10,8 @@ import { ...@@ -10,6 +10,8 @@ import {
Keyboard, Keyboard,
SafeAreaView, SafeAreaView,
Image, Image,
StatusBar, // FEATURE: Import StatusBar để control status bar
Platform, // FEATURE: Check platform iOS/Android
} from "react-native"; } from "react-native";
import HeaderCus from "../home/header"; import HeaderCus from "../home/header";
import R from "../../assets/R"; import R from "../../assets/R";
...@@ -18,6 +20,7 @@ import ItemGrid from "./item"; ...@@ -18,6 +20,7 @@ import ItemGrid from "./item";
import styles from "./style"; import styles from "./style";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import * as SCREENNAME from "../../routers/ScreenNames"; import * as SCREENNAME from "../../routers/ScreenNames";
const HomeView = (props) => { const HomeView = (props) => {
const { const {
menuDataStudy, menuDataStudy,
...@@ -29,119 +32,143 @@ const HomeView = (props) => { ...@@ -29,119 +32,143 @@ const HomeView = (props) => {
onMenuItemPress, onMenuItemPress,
onSearchChange, onSearchChange,
} = props; } = props;
// OPTIMIZE: Move icon reference outside render để tránh re-create
const ArrowRightIcon = R.images.icArrowRight; const ArrowRightIcon = R.images.icArrowRight;
const navigate = useNavigation(); const navigate = useNavigation();
const renderMenuItem = ({ item }) => {
return <ItemGrid item={item} onPress={() => onMenuItemPress(item)} />;
};
return ( // PERFORMANCE: Memoized render function
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}> const renderMenuItem = React.useCallback(({ item }) => {
<SafeAreaView style={{ flex: 1 }}> return <ItemGrid item={item} onPress={() => onMenuItemPress(item)} />;
}, [onMenuItemPress]);
<View style={styles.container_body}> // UI/UX: Profile card component với null safety
<ImageBackground const renderProfileCard = () => (
source={R.images.igBackgroundSlider} <View style={styles.profile_card}>
style={styles.background_header} <View style={styles.profile_left}>
> {/* FEATURE: Avatar với fallback */}
<HeaderCus <View style={styles.avatar}>
pathLogo={R.images.igLogo} {userProfile?.avatar ? (
width={75} <Image
height={36} source={{ uri: userProfile.avatar }}
textInput={R.colors.white} style={styles.avatar_image}
backgroundInput={R.colors.backgroundInputSearch} resizeMode="cover"
textLabel={I18n.t("Search")}
textColorLabel={R.colors.white}
/> />
) : (
<View style={styles.avatar_placeholder}>
<Text style={styles.avatar_text}>
{userProfile?.name?.charAt(0) || "U"}
</Text>
</View>
)}
</View>
{/* FEATURE: User information với null safety */}
<View style={styles.information}>
<Text
style={styles.text_card_info}
numberOfLines={1}
ellipsizeMode="tail"
>
{userProfile?.name || "Không có tên"}
</Text>
<Text
style={styles.text_card_info}
numberOfLines={1}
ellipsizeMode="tail"
>
{userProfile?.phone || "Không có SĐT"}
</Text>
</View>
</View>
<View style={styles.profile_card}> {/* FEATURE: Profile button với better UX */}
<View style={styles.profile_left}> <TouchableOpacity
<View style={styles.avatar}> style={styles.profile_btn}
{userProfile?.avatar ? ( onPress={() => navigate.navigate(SCREENNAME.PROFILE)}
<Image activeOpacity={0.7}
source={{ uri: userProfile.avatar }} >
style={styles.avatar_image} <Text style={styles.btn_text}>H s cá nhân</Text>
resizeMode="cover" <ArrowRightIcon
/> width={5}
) : ( height={10}
<View style={styles.avatar_placeholder}> fill={R.colors.txtMain}
<Text style={styles.avatar_text}> style={styles.icon}
{userProfile?.name?.charAt(0)} />
</Text> </TouchableOpacity>
</View> </View>
)} );
</View>
<View style={styles.information}>
<Text
style={styles.text_card_info}
numberOfLines={1}
ellipsizeMode="tail"
>
{userProfile?.name}
</Text>
<Text
style={styles.text_card_info}
numberOfLines={1}
ellipsizeMode="tail"
>
{userProfile?.phone}
</Text>
</View>
</View>
<TouchableOpacity style={styles.profile_btn} onPress={() => navigate.navigate(SCREENNAME.PROFILE)}> // FUNCTIONALITY: Render menu section với reusable logic
<Text style={styles.btn_text}>H sơ cá nhân</Text> const renderMenuSection = (title, data) => (
<ArrowRightIcon <View style={styles.menu_container}>
width={5} <Text style={styles.menu_title}>{title}</Text>
height={10} <FlatList
fill={R.colors.txtMain} data={data}
style={styles.icon} renderItem={renderMenuItem}
/> numColumns={3}
</TouchableOpacity> keyExtractor={(item) => item.id.toString()}
</View> scrollEnabled={false}
</ImageBackground> columnWrapperStyle={styles.row}
<ScrollView removeClippedSubviews={true} // PERFORMANCE: Memory optimization
showsVerticalScrollIndicator={false} maxToRenderPerBatch={9} // PERFORMANCE: Render batch size
style={styles.scroll}> windowSize={10} // PERFORMANCE: Window size optimization
<View style={styles.menu_container}> />
<Text style={styles.menu_title}>Hc tp</Text> </View>
<FlatList );
data={menuDataStudy}
renderItem={renderMenuItem} return (
numColumns={3} <>
keyExtractor={(item) => item.id.toString()} {/* FIXME: StatusBar configuration để loại bỏ white space */}
scrollEnabled={false} <StatusBar
columnWrapperStyle={styles.row} barStyle="light-content" // Text trắng trên dark background
/> backgroundColor="transparent" // Background trong suốt
</View> translucent={true} // Cho phép content extend lên status bar
<View style={styles.menu_container}> />
<Text style={styles.menu_title}>Cá nhân</Text>
<FlatList <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
data={menuDataIndividual} {/* FIXME: Dùng View với manual padding thay SafeAreaView */}
renderItem={renderMenuItem} <View style={[
numColumns={3} { flex: 1 },
keyExtractor={(item) => item.id.toString()} { paddingTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight }
scrollEnabled={false} ]}>
columnWrapperStyle={styles.row} <View style={styles.container_body}>
/> <ImageBackground
</View> source={R.images.igBackgroundSlider}
<View style={styles.menu_container}> style={[styles.background_header, {
<Text style={styles.menu_title}>Dch v trc tuyến</Text> // FIXME: Extend background để cover status bar area
<FlatList paddingTop: Platform.OS === 'ios' ? 50 : (StatusBar.currentHeight || 0) + 10,
data={menuDataOnlineSer} }]}
renderItem={renderMenuItem} >
numColumns={3} <HeaderCus
keyExtractor={(item) => item.id.toString()} pathLogo={R.images.igLogo}
scrollEnabled={false} width={75}
columnWrapperStyle={styles.row} height={36}
textInput={R.colors.white}
backgroundInput={R.colors.backgroundInputSearch}
textLabel={I18n.t("Search")}
textColorLabel={R.colors.white}
/> />
</View>
</ScrollView> {renderProfileCard()}
</ImageBackground>
<ScrollView
showsVerticalScrollIndicator={false}
style={styles.scroll}
bounces={false} // OPTIMIZE: Tắt bounce trên iOS
overScrollMode="never" // OPTIMIZE: Tắt over scroll trên Android
>
{/* FUNCTIONALITY: Render các menu sections */}
{renderMenuSection("Học tập", menuDataStudy)}
{renderMenuSection("Cá nhân", menuDataIndividual)}
{renderMenuSection("Dịch vụ trực tuyến", menuDataOnlineSer)}
</ScrollView>
</View>
</View> </View>
</SafeAreaView> </TouchableWithoutFeedback>
</TouchableWithoutFeedback> </>
); );
}; };
export default HomeView; export default HomeView;
\ No newline at end of file
...@@ -18,7 +18,7 @@ const ProfileView = (props) => { ...@@ -18,7 +18,7 @@ const ProfileView = (props) => {
const { phone, setPhone, cmnd, setCmnd, bank, setBank } = props; const { phone, setPhone, cmnd, setCmnd, bank, setBank } = props;
const IconCamera = R.images.icCamera; const IconCamera = R.images.icCamera;
return ( return (
<SafeAreaView style={{ flex: 1, backgroundColor: R.colors.white }}> <View style={{ flex: 1}}>
<Header title={"Hồ sơ cá nhân"} isBack /> <Header title={"Hồ sơ cá nhân"} isBack />
<ScrollView showsVerticalScrollIndicator={false} style={{ flex: 1 }}> <ScrollView showsVerticalScrollIndicator={false} style={{ flex: 1 }}>
<View style={styles.container}> <View style={styles.container}>
...@@ -335,7 +335,7 @@ const ProfileView = (props) => { ...@@ -335,7 +335,7 @@ const ProfileView = (props) => {
</View> </View>
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView> </View>
); );
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment