diff --git a/components/layout/ask.tsx b/components/layout/ask.tsx
index 3a8445b..d0c36de 100644
--- a/components/layout/ask.tsx
+++ b/components/layout/ask.tsx
@@ -3,87 +3,166 @@ import ChatNotInSvg from "@/assets/icons/svg/chatNotIn.svg";
import PersonInSvg from "@/assets/icons/svg/personIn.svg";
import PersonNotInSvg from "@/assets/icons/svg/personNotIn.svg";
import { router, usePathname } from "expo-router";
-import React from 'react';
-import { Dimensions, Image, Platform, TouchableOpacity, View } from 'react-native';
-import { Circle, Ellipse, G, Mask, Path, Rect, Svg } from 'react-native-svg';
+import React, { useCallback, useEffect, useMemo } from 'react';
+import { Dimensions, Image, StyleSheet, TouchableOpacity, View } from 'react-native';
+import Svg, { Circle, Ellipse, G, Mask, Path, Rect } from "react-native-svg";
+
+// 使用 React.memo 包装 SVG 组件,避免不必要的重渲染
+const TabIcon = React.memo(({ isActive, ActiveIcon, InactiveIcon }: {
+ isActive: boolean;
+ ActiveIcon: React.FC<{ width: number; height: number }>;
+ InactiveIcon: React.FC<{ width: number; height: number }>;
+}) => {
+ const Icon = isActive ? ActiveIcon : InactiveIcon;
+ return ;
+});
+
+// 提取 SVG 组件,避免重复渲染
+const CenterButtonSvg = React.memo(() => (
+
+));
const AskNavbar = () => {
// 获取设备尺寸
- const { width } = Dimensions.get('window');
- // 获取路由
+ const { width } = useMemo(() => Dimensions.get('window'), []);
const pathname = usePathname();
- return (
- {
+ const preloadPages = async () => {
+ try {
+ await Promise.all([
+ router.prefetch('/memo-list'),
+ router.prefetch('/ask'),
+ router.prefetch('/owner')
+ ]);
+ } catch (error) {
+ console.warn('预加载页面失败:', error);
+ }
+ };
+ preloadPages();
+ }, []);
+
+ // 使用 useCallback 缓存导航函数
+ const navigateTo = useCallback((route: string) => {
+ if (route === '/ask') {
+ router.push({
+ pathname: '/ask',
+ params: { newSession: "true" }
+ });
+ } else {
+ router.push(route as any);
+ }
+ }, []);
+
+ // 使用 useMemo 缓存样式对象
+ const styles = useMemo(() => StyleSheet.create({
+ container: {
+ position: 'absolute',
+ bottom: 0,
+ left: 0,
+ right: 0,
+ backgroundColor: 'white',
shadowColor: '#000',
- shadowOffset: { width: 0, height: -4 }, // Negative height for bottom shadow
+ shadowOffset: { width: 0, height: -4 },
shadowOpacity: 0.1,
shadowRadius: 8,
- elevation: 10, // For Android
- }}>
- {/* */}
+ elevation: 10,
+ },
+ backgroundImage: {
+ width,
+ height: 80,
+ resizeMode: 'cover'
+ },
+ navButton: {
+ padding: 16
+ },
+ navContainer: {
+ position: 'absolute',
+ bottom: 0,
+ left: 0,
+ right: 0,
+ height: 80, // Set a fixed height for the navbar
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ paddingHorizontal: 32,
+ backgroundColor: 'transparent', // Make sure it's transparent
+ },
+ centerButton: {
+ position: 'absolute',
+ left: width / 2,
+ top: -42.5, // Adjust this value to move the button up or down
+ marginLeft: -42.5, // Half of the button width (85/2)
+ width: 85,
+ height: 85,
+ justifyContent: 'center',
+ alignItems: 'center',
+ shadowColor: '#FFB645',
+ shadowOffset: { width: 0, height: 4 },
+ shadowOpacity: 0.3,
+ shadowRadius: 8,
+ elevation: 8,
+ borderRadius: 50,
+ backgroundColor: 'transparent',
+ zIndex: 10,
+ }
+ }), [width]);
+
+ return (
+
-
- router.push('/memo-list')} style={{ padding: 16 }}>
- {pathname === "/memo-list" ? : }
+
+ navigateTo('/memo-list')}
+ style={styles.navButton}
+ >
+
{
- router.push({
- pathname: '/ask',
- params: { newSession: "true" }
- });
- }}
- className={`${Platform.OS === 'web' ? '-mt-[4rem]' : width <= 375 ? '-mt-[5rem]' : '-mt-[5rem]'}`}
+ onPress={() => navigateTo('/ask')}
+ style={styles.centerButton}
>
-
-
-
+
- router.push('/owner')} style={{ padding: 16 }}>
-
- {pathname === "/owner" ? : }
- {/* */}
-
+
+ navigateTo('/owner')}
+ style={styles.navButton}
+ >
+
);
};
-export default AskNavbar;
\ No newline at end of file
+export default React.memo(AskNavbar);
\ No newline at end of file