最终效果

点击搜索输入框后

注意事项
商品搜索为背景透明的单独页面,便于代码解耦 !
代码实现
app/(tabs)/shop.tsx
c
import AntDesign from "@expo/vector-icons/AntDesign";
import { useRouter } from "expo-router";
import {
Dimensions,
FlatList,
Image,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
const { width: SCREEN_WIDTH } = Dimensions.get("window");
const ITEM_WIDTH = (SCREEN_WIDTH - 18) >> 1;
export default function ShopScreen() {
const router = useRouter();
const onSearchPress = () => {
router.push("/searchGoods");
};
const goodsList = [
{
id: 1,
title: "纯小麦粉面粉无小麦麸质低脂杂粮糖友敏宝牛油果果桥本·700g*3袋装",
image:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage109.360doc.com%2FDownloadImg%2F2021%2F06%2F1618%2F224298760_2_20210616063501614&refer=http%3A%2F%2Fimage109.360doc.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1754646069&t=46ad4dd7d2215498aecafa09558bac63",
price: 51,
originPrice: undefined,
promotion: undefined,
},
{
id: 2,
title: "糙米米粉江西米线南仓拌粉螺狮粉800g粗粮无小麦麸",
image:
"https://ww4.sinaimg.cn/mw690/007I08aHly8hxw2fy44z2j30m80m8jtv.jpg",
price: 84,
originPrice: undefined,
promotion: undefined,
},
{
id: 3,
title: "手作一鸣禅意大合集9.9r全新款绕指柔串12mm圆珠抹茶芝士大合集",
image:
"https://img2.baidu.com/it/u=1752777421,933296832&fm=253&app=138&f=JPEG?w=800&h=1200",
price: 9.9,
originPrice: 12.8,
promotion: undefined,
},
{
id: 4,
title: "山核桃手串文玩核桃手串手持珠串小核桃串手挂可爆浆深山采核桃",
image:
"https://img1.baidu.com/it/u=1640157490,2252140535&fm=253&app=138&f=JPEG?w=500&h=736",
price: 9.9,
originPrice: undefined,
promotion: undefined,
},
{
id: 5,
title: "纯色素珠5.6R拼手速·纯绿11*12mm",
image:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fbea04f46-dd1a-46f9-8c30-f98c3617b24d%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1754645565&t=621fb0466253ddda8b74888c6fd6c56f",
price: 5.8,
originPrice: undefined,
promotion: undefined,
},
{
id: 6,
title: "天然绿檀木佛珠手串老料和田玉檀香木链男女民族饰品手串",
image:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcbu01.alicdn.com%2Fimg%2Fibank%2FO1CN01EbmBWk1YtAzaWm0Tb_%21%211647433116-0-cib.jpg&refer=http%3A%2F%2Fcbu01.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1754645594&t=e3bd317daf5611cdb2ef1781056cc775",
price: 12,
originPrice: undefined,
promotion: undefined,
},
{
id: 7,
title: "黄油椰子素酥咸蛋黄酥脆饼干椰蓉酥糕点零食酥到没朋友咖啡椰子酥",
image:
"https://img2.baidu.com/it/u=2300908930,1727378078&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1067",
price: 15.8,
originPrice: undefined,
promotion: "满100减18",
},
{
id: 8,
title: "厚切吐司面包奶香味提拉米苏味手撕面包14袋整箱装混合口味",
image:
"https://t13.baidu.com/it/u=3725456725,3923692805&fm=224&app=112&f=JPEG?w=500&h=500",
price: 19.9,
originPrice: 25.98,
promotion: undefined,
},
];
const categoryList = [
{
id: 1,
name: "蔬菜",
image:
"https://img01.yzcdn.cn/upload_files/2021/03/08/Fg6Qp_A8ScuIlSdv5ImHRAwvNFSk.jpg!middle.jpg",
},
{
id: 2,
name: "鞋子",
image:
"https://imgservice.suning.cn/uimg1/b2c/image/P5wpAyAvGZuwAuR7WqTFsg.jpg_800w_800h_4e",
},
{
id: 3,
name: "收纳盒",
image:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fbao%2Fuploaded%2Fi4%2F690591437%2FO1CN01SKPhW01MUBhz5wV73_%21%21690591437.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1754644995&t=96299f549a7ce4947700b3d11424be73",
},
{
id: 4,
name: "水果",
image:
"https://m.360buyimg.com/mobilecms/s750x750_jfs/t2641/47/1902721556/127381/3cfb874d/574e99a2Nce76f409.jpg!q80.jpg",
},
{
id: 5,
name: "酒水",
image:
"https://m.360buyimg.com/mobilecms/s750x750_jfs/t17581/178/845387461/322822/5428cef1/5aa9d5c7N8d0ad290.jpg!q80.jpg",
},
{
id: 6,
name: "饼干",
image:
"https://img01.yzcdn.cn/upload_files/2021/07/12/8db487f504549b2738ef3f77b7aa2232.jpg!middle.jpg",
},
{
id: 7,
name: "电脑椅",
image:
"https://pic.rmb.bdstatic.com/bjh/down/dc41f9f74d70e08b5877df601c381c42.jpeg@wm_2,t_55m+5a625Y+3L+enn+S4gOermeS6jOaJi+WKnuWFrOWutuWFtw==,fc_ffffff,ff_U2ltSGVp,sz_20,x_13,y_13",
},
{
id: 8,
name: "包包",
image: "https://p4.zbjimg.com/task/2013-07/24/works/51ef5093662ef.jpg",
},
{
id: 9,
name: "行李箱",
image:
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcbu01.alicdn.com%2Fimg%2Fibank%2FO1CN014NJo3c26XMySVASfM_%21%212209736787671-0-cib.jpg&refer=http%3A%2F%2Fcbu01.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1754645294&t=b0f52e5ea829f6b8c31b672446ec964b",
},
{
id: 10,
name: "鸡蛋",
image:
"https://img20.360buyimg.com/ceco/jfs/t1/149790/20/10889/119725/5f883afeE9f15bcae/e6611d4bc27acf78.jpg!q70.jpg",
},
];
const ListHeader = () => {
const styles = StyleSheet.create({
container: {
width: "100%",
flexDirection: "row",
flexWrap: "wrap",
padding: 10,
},
categoryItem: {
width: "20%",
alignItems: "center",
paddingVertical: 16,
},
itemImg: {
width: 40,
height: 40,
resizeMode: "contain",
},
itemNameTxt: {
fontSize: 14,
color: "#333",
marginTop: 6,
},
});
return (
<View style={styles.container}>
{categoryList.map((item) => {
return (
<View key={`${item.id}`} style={styles.categoryItem}>
<Image style={styles.itemImg} source={{ uri: item.image }} />
<Text style={styles.itemNameTxt}>{item.name}</Text>
</View>
);
})}
</View>
);
};
const renderItem = ({ item }: { item: GoodsSimple; index: number }) => {
const styles = StyleSheet.create({
item: {
width: ITEM_WIDTH,
borderRadius: 8,
overflow: "hidden",
marginLeft: 6,
marginTop: 6,
marginBottom: 8,
},
img: {
width: "100%",
height: 200,
resizeMode: "cover",
},
titleTxt: {
fontSize: 14,
color: "#333",
marginTop: 6,
},
prefix: {
fontSize: 14,
color: "#333",
fontWeight: "bold",
marginTop: 4,
},
priceTxt: {
fontSize: 22,
color: "#333",
fontWeight: "bold",
textAlign: "justify",
},
originTxt: {
fontSize: 13,
color: "#999",
fontWeight: "normal",
},
promotionTxt: {
width: 78,
fontSize: 12,
color: "#999",
borderRadius: 2,
borderWidth: 1,
borderColor: "#bbb",
textAlign: "center",
marginTop: 4,
},
});
return (
<View style={styles.item}>
<Image style={styles.img} source={{ uri: item.image }} />
<Text style={styles.titleTxt}>{item.title}</Text>
{!!item.promotion && (
<Text style={styles.promotionTxt}>{item.promotion}</Text>
)}
<Text style={styles.prefix}>
¥
<Text style={styles.priceTxt}>
{item.price}{" "}
{!!item.originPrice && (
<Text style={styles.originTxt}>原价:{item.originPrice}</Text>
)}
</Text>
</Text>
</View>
);
};
return (
<View style={styles.page}>
<View style={styles.topBar}>
<TouchableOpacity style={styles.searchBox} onPress={onSearchPress}>
<AntDesign name="search1" size={18} color="grey" />
<Text style={styles.searchTxt}>米粉</Text>
</TouchableOpacity>
<AntDesign
style={styles.iconBtn}
name="shoppingcart"
size={22}
color="grey"
/>
<AntDesign
style={styles.iconBtn}
name="profile"
size={22}
color="grey"
/>
<AntDesign
style={styles.iconBtn}
name="ellipsis1"
size={22}
color="grey"
/>
</View>
<FlatList
style={{ flex: 1 }}
data={goodsList}
keyExtractor={(item) => `${item.id}`}
extraData={[categoryList]}
renderItem={renderItem}
numColumns={2}
ListHeaderComponent={<ListHeader />}
/>
</View>
);
}
const styles = StyleSheet.create({
page: {
width: "100%",
height: "100%",
backgroundColor: "white",
},
iconBtn: {
marginLeft: 10,
},
topBar: {
width: "100%",
height: 40,
flexDirection: "row",
alignItems: "center",
paddingHorizontal: 16,
},
searchBox: {
height: 32,
flex: 1,
backgroundColor: "#f0f0f0",
borderRadius: 16,
flexDirection: "row",
alignItems: "center",
paddingHorizontal: 16,
},
searchTxt: {
width: "100%",
fontSize: 14,
color: "#bbb",
marginLeft: 10,
},
});
app/searchGoods.tsx
背景色为透明!
c
import AntDesign from "@expo/vector-icons/AntDesign";
import { useRouter } from "expo-router";
import React, { useEffect, useRef } from "react";
import {
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
export default function MineScreen() {
const inputRef = useRef<TextInput>(null);
const router = useRouter();
useEffect(() => {
setTimeout(() => {
inputRef.current?.focus();
}, 100);
}, []);
return (
<View style={styles.page}>
<View style={styles.topBar}>
<TouchableOpacity
style={styles.backButton}
onPress={() => router.back()}
>
<AntDesign name="left" size={24} color="black" />
</TouchableOpacity>
<View style={styles.searchLayout}>
<AntDesign name="search1" size={18} color="grey" />
<TextInput
ref={inputRef}
style={styles.searchTxt}
placeholder="纯粮小麦粉"
placeholderTextColor={"#bbb"}
/>
</View>
<Text style={styles.searchBotton}>搜索</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
page: {
width: "100%",
height: "100%",
backgroundColor: "transparent",
},
searchLayout: {
height: 32,
flex: 1,
backgroundColor: "#f0f0f0",
borderRadius: 16,
flexDirection: "row",
alignItems: "center",
paddingHorizontal: 16,
marginLeft: 16,
},
searchTxt: {
height: "100%",
fontSize: 14,
color: "#bbb",
marginLeft: 6,
paddingHorizontal: 8,
paddingVertical: 0,
paddingTop: 8,
textAlignVertical: "center",
},
searchBotton: {
fontSize: 16,
color: "#666",
marginHorizontal: 12,
},
topBar: {
display: "flex",
width: "100%",
height: 40,
flexDirection: "row",
alignItems: "center",
backgroundColor: "white",
},
backButton: {
height: "100%",
paddingLeft: 16,
justifyContent: "center",
},
});
app/_layout.tsx
给商品搜索页注册路由,配置其为透明模式。
c
<Stack.Screen
name="searchGoods"
options={{
headerShown: false,
presentation: "transparentModal",
}}
/>