You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
312 lines
8.7 KiB
312 lines
8.7 KiB
2 months ago
|
import React, { useCallback } from 'react';
|
||
|
import {
|
||
|
View,
|
||
|
Text,
|
||
|
StyleSheet,
|
||
|
ScrollView,
|
||
|
TouchableOpacity,
|
||
|
SafeAreaView,
|
||
|
InteractionManager
|
||
|
} from 'react-native';
|
||
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
||
|
import { useNavigation } from '@react-navigation/native';
|
||
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||
|
|
||
|
// Define type for icon props
|
||
|
type IconProps = {
|
||
|
name: string;
|
||
|
size: number;
|
||
|
color: string;
|
||
|
};
|
||
|
|
||
|
// Helper component for icons - 使用React.memo优化渲染
|
||
|
const IconComponent = React.memo(({ name, size, color }: IconProps) => {
|
||
|
const Icon = Ionicons as any;
|
||
|
return <Icon name={name} size={size} color={color} />;
|
||
|
});
|
||
|
|
||
|
export const HomeScreen = () => {
|
||
|
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
||
|
|
||
|
// 导航到搜索页面 - 使用useCallback优化函数引用
|
||
|
const navigateToSearch = useCallback(() => {
|
||
|
// 使用InteractionManager延迟执行导航操作,确保当前交互和动画已完成
|
||
|
InteractionManager.runAfterInteractions(() => {
|
||
|
navigation.navigate('Search');
|
||
|
});
|
||
|
}, [navigation]);
|
||
|
|
||
|
return (
|
||
|
<SafeAreaView style={styles.container}>
|
||
|
{/* Search Bar */}
|
||
|
<View style={styles.searchContainer}>
|
||
|
<TouchableOpacity
|
||
|
style={styles.searchBar}
|
||
|
activeOpacity={0.7}
|
||
|
onPress={navigateToSearch}
|
||
|
>
|
||
|
<IconComponent name="search-outline" size={20} color="#999" />
|
||
|
<Text style={styles.searchPlaceholder}>搜索商品</Text>
|
||
|
</TouchableOpacity>
|
||
|
<TouchableOpacity style={styles.cameraButton}>
|
||
|
<IconComponent name="camera-outline" size={24} color="#333" />
|
||
|
</TouchableOpacity>
|
||
|
</View>
|
||
|
|
||
|
<ScrollView
|
||
|
showsVerticalScrollIndicator={false}
|
||
|
keyboardShouldPersistTaps="handled"
|
||
|
>
|
||
|
{/* Banner */}
|
||
|
<View style={styles.bannerContainer}>
|
||
|
<Text style={styles.bannerText}>banner picture</Text>
|
||
|
</View>
|
||
|
|
||
|
{/* Service Options */}
|
||
|
<View style={styles.serviceContainer}>
|
||
|
<TouchableOpacity style={styles.serviceItem}>
|
||
|
<View style={styles.serviceIconBg}>
|
||
|
<Text style={styles.serviceIcon}>🚢</Text>
|
||
|
</View>
|
||
|
<Text style={styles.serviceText}>Shipping</Text>
|
||
|
</TouchableOpacity>
|
||
|
|
||
|
<TouchableOpacity style={styles.serviceItem}>
|
||
|
<View style={styles.serviceIconBg}>
|
||
|
<Text style={styles.serviceIcon}>💰</Text>
|
||
|
</View>
|
||
|
<Text style={styles.serviceText}>Quote</Text>
|
||
|
</TouchableOpacity>
|
||
|
|
||
|
<TouchableOpacity style={styles.serviceItem}>
|
||
|
<View style={styles.serviceIconBg}>
|
||
|
<Text style={styles.serviceIcon}>📱</Text>
|
||
|
</View>
|
||
|
<Text style={styles.serviceText}>TikTok</Text>
|
||
|
</TouchableOpacity>
|
||
|
|
||
|
<TouchableOpacity style={styles.serviceItem}>
|
||
|
<View style={styles.serviceIconBg}>
|
||
|
<Text style={[styles.serviceIcon, {color: 'red'}]}>❓</Text>
|
||
|
</View>
|
||
|
<Text style={styles.serviceText}>How to Buy</Text>
|
||
|
</TouchableOpacity>
|
||
|
</View>
|
||
|
|
||
|
{/* Category Buttons */}
|
||
|
<View style={styles.categoryContainer}>
|
||
|
<ScrollView
|
||
|
horizontal
|
||
|
showsHorizontalScrollIndicator={false}
|
||
|
contentContainerStyle={styles.categoryScrollContent}
|
||
|
>
|
||
|
<TouchableOpacity style={[styles.categoryButton, styles.categoryActive]}>
|
||
|
<Text style={[styles.categoryText, styles.categoryActiveText]}>All</Text>
|
||
|
</TouchableOpacity>
|
||
|
<TouchableOpacity style={styles.categoryButton}>
|
||
|
<Text style={styles.categoryText}>Electronics</Text>
|
||
|
</TouchableOpacity>
|
||
|
<TouchableOpacity style={styles.categoryButton}>
|
||
|
<Text style={styles.categoryText}>Clothing</Text>
|
||
|
</TouchableOpacity>
|
||
|
<TouchableOpacity style={styles.categoryButton}>
|
||
|
<Text style={styles.categoryText}>Home</Text>
|
||
|
</TouchableOpacity>
|
||
|
<TouchableOpacity style={styles.categoryButton}>
|
||
|
<Text style={styles.categoryText}>Beauty</Text>
|
||
|
</TouchableOpacity>
|
||
|
<TouchableOpacity style={styles.categoryButton}>
|
||
|
<Text style={styles.categoryText}>Kids</Text>
|
||
|
</TouchableOpacity>
|
||
|
</ScrollView>
|
||
|
</View>
|
||
|
|
||
|
{/* Product Grid */}
|
||
|
<View style={styles.productGrid}>
|
||
|
{/* Product 1 */}
|
||
|
<View style={styles.productCard}>
|
||
|
<View style={styles.productImageContainer}>
|
||
|
<Text style={styles.placeholderText}>product picture</Text>
|
||
|
</View>
|
||
|
<View style={styles.productInfo}>
|
||
|
<Text style={styles.productPrice}>$29.99</Text>
|
||
|
<Text style={styles.productTitle} numberOfLines={2}>
|
||
|
Wireless Bluetooth Earbuds
|
||
|
</Text>
|
||
|
<Text style={styles.productSales}>Monthly Sales: 1,234</Text>
|
||
|
</View>
|
||
|
</View>
|
||
|
|
||
|
{/* Product 2 */}
|
||
|
<View style={styles.productCard}>
|
||
|
<View style={styles.productImageContainer}>
|
||
|
<Text style={styles.placeholderText}>product picture</Text>
|
||
|
</View>
|
||
|
<View style={styles.productInfo}>
|
||
|
<Text style={[styles.productPrice, {color: '#ff6600'}]}>€19.99</Text>
|
||
|
<Text style={styles.productTitle} numberOfLines={2}>
|
||
|
Portable Power Bank 10000
|
||
|
</Text>
|
||
|
<Text style={styles.productSales}>Monthly Sales: 2,350</Text>
|
||
|
</View>
|
||
|
</View>
|
||
|
|
||
|
{/* More products */}
|
||
|
<View style={styles.productCard}>
|
||
|
<View style={styles.productImageContainer}>
|
||
|
<Text style={styles.placeholderText}>product picture</Text>
|
||
|
</View>
|
||
|
</View>
|
||
|
|
||
|
<View style={styles.productCard}>
|
||
|
<View style={styles.productImageContainer}>
|
||
|
<Text style={styles.placeholderText}>product picture</Text>
|
||
|
</View>
|
||
|
</View>
|
||
|
</View>
|
||
|
</ScrollView>
|
||
|
</SafeAreaView>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
const styles = StyleSheet.create({
|
||
|
container: {
|
||
|
flex: 1,
|
||
|
backgroundColor: '#f5f5f5',
|
||
|
},
|
||
|
safeArea: {
|
||
|
flex: 1,
|
||
|
},
|
||
|
searchContainer: {
|
||
|
flexDirection: 'row',
|
||
|
paddingHorizontal: 15,
|
||
|
paddingVertical: 10,
|
||
|
backgroundColor: '#fff',
|
||
|
alignItems: 'center',
|
||
|
},
|
||
|
searchBar: {
|
||
|
flex: 1,
|
||
|
flexDirection: 'row',
|
||
|
alignItems: 'center',
|
||
|
backgroundColor: '#f0f0f0',
|
||
|
borderRadius: 20,
|
||
|
paddingHorizontal: 15,
|
||
|
height: 40,
|
||
|
},
|
||
|
searchPlaceholder: {
|
||
|
flex: 1,
|
||
|
marginLeft: 8,
|
||
|
fontSize: 16,
|
||
|
},
|
||
|
cameraButton: {
|
||
|
marginLeft: 10,
|
||
|
padding: 5,
|
||
|
},
|
||
|
bannerContainer: {
|
||
|
height: 180,
|
||
|
backgroundColor: '#e0e0e0',
|
||
|
marginHorizontal: 15,
|
||
|
marginTop: 15,
|
||
|
borderRadius: 8,
|
||
|
alignItems: 'center',
|
||
|
justifyContent: 'center',
|
||
|
},
|
||
|
bannerText: {
|
||
|
color: '#999',
|
||
|
fontSize: 20,
|
||
|
},
|
||
|
serviceContainer: {
|
||
|
flexDirection: 'row',
|
||
|
justifyContent: 'space-around',
|
||
|
backgroundColor: '#fff',
|
||
|
marginHorizontal: 15,
|
||
|
marginTop: 15,
|
||
|
borderRadius: 12,
|
||
|
padding: 15,
|
||
|
},
|
||
|
serviceItem: {
|
||
|
alignItems: 'center',
|
||
|
},
|
||
|
serviceIconBg: {
|
||
|
width: 50,
|
||
|
height: 50,
|
||
|
borderRadius: 25,
|
||
|
backgroundColor: '#f0f0f0',
|
||
|
justifyContent: 'center',
|
||
|
alignItems: 'center',
|
||
|
marginBottom: 8,
|
||
|
},
|
||
|
serviceIcon: {
|
||
|
fontSize: 24,
|
||
|
},
|
||
|
serviceText: {
|
||
|
fontSize: 14,
|
||
|
color: '#333',
|
||
|
},
|
||
|
categoryContainer: {
|
||
|
marginTop: 15,
|
||
|
paddingVertical: 10,
|
||
|
backgroundColor: '#fff',
|
||
|
},
|
||
|
categoryScrollContent: {
|
||
|
paddingHorizontal: 10,
|
||
|
},
|
||
|
categoryButton: {
|
||
|
paddingHorizontal: 20,
|
||
|
paddingVertical: 10,
|
||
|
borderRadius: 20,
|
||
|
marginHorizontal: 5,
|
||
|
backgroundColor: '#f0f0f0',
|
||
|
},
|
||
|
categoryActive: {
|
||
|
backgroundColor: '#ff6600',
|
||
|
},
|
||
|
categoryText: {
|
||
|
color: '#666',
|
||
|
fontWeight: '500',
|
||
|
},
|
||
|
categoryActiveText: {
|
||
|
color: '#fff',
|
||
|
},
|
||
|
productGrid: {
|
||
|
flexDirection: 'row',
|
||
|
flexWrap: 'wrap',
|
||
|
padding: 10,
|
||
|
justifyContent: 'space-between',
|
||
|
},
|
||
|
productCard: {
|
||
|
width: '48%',
|
||
|
backgroundColor: '#fff',
|
||
|
borderRadius: 8,
|
||
|
marginBottom: 15,
|
||
|
overflow: 'hidden',
|
||
|
},
|
||
|
productImageContainer: {
|
||
|
height: 150,
|
||
|
backgroundColor: '#e0e0e0',
|
||
|
alignItems: 'center',
|
||
|
justifyContent: 'center',
|
||
|
},
|
||
|
placeholderText: {
|
||
|
color: '#999',
|
||
|
fontSize: 16,
|
||
|
},
|
||
|
productInfo: {
|
||
|
padding: 10,
|
||
|
},
|
||
|
productPrice: {
|
||
|
fontSize: 18,
|
||
|
fontWeight: 'bold',
|
||
|
color: '#ff6600',
|
||
|
marginBottom: 5,
|
||
|
},
|
||
|
productTitle: {
|
||
|
fontSize: 14,
|
||
|
color: '#333',
|
||
|
marginBottom: 5,
|
||
|
},
|
||
|
productSales: {
|
||
|
fontSize: 12,
|
||
|
color: '#999',
|
||
|
}
|
||
|
});
|