【React Native】布局文件-顶部导航栏
配置导航栏标题
希望顶部的标题,就显示成首页
,而不要显示成index
。
<Stack . Screen options={{ title: "首页" }} />
但一定记住,需要同时又 _layout.js
的中 Stack 的支持才可以生效。
同时传参为:
<View style={styles.container}><Stack.Screen options={{ title: "首页" }} /><Text style={styles.title}>这里是首页</Text><Link style={styles.link} href="/courses/1?title=Node.js">跳转传参(Link)</Link><Linkstyle={styles.link}href={{pathname: "/courses/[id]",params: { id: 2, title: "React Native" },}}>跳转传参(Link 使用 params)</Link><TouchableOpacityonPress={() => router.navigate("/courses/3?title=Vue.js")}><Text style={styles.buttonText}>跳转传参(navigate )</Text></TouchableOpacity><TouchableOpacityonPress={() =>router.navigate({pathname: "/courses/[id]",params: { id: 4, title: "微信小程序" },})}><Text style={styles.buttonText}>跳转传参(navigate 使用 params )</Text></TouchableOpacity></View>
export default function Course() {const { id, title } = useLocalSearchParams();return (<View style={styles.container}><Stack.Screen options={{ title: title }}/>// ...</View>);
}
也可以使用 router 设置 params:
export default function Course() {const router = useRouter();//...return (<View style={styles.container}>// ...<TouchableOpacity onPress={() => router.setParams({ title: 'params被修改了!' })}><Text style={styles.buttonText}>修改params</Text></TouchableOpacity></View>);
}
布局文件-顶部导航栏
统一配置导航栏样式
但是现在这个样式只是在首页才有,如果切换到其他页面就没有了。所以我们可以将这些公共的样式header放入到布局文件 _layout.js
中。
import { Stack } from 'expo-router';export default function Layout() {return (<StackscreenOptions={{headerTitleAlign: 'center', // 安卓标题栏居中animation: 'slide_from_right', // 安卓使用左右切屏headerStyle: { // 导航栏整体样式backgroundColor: '#e29447'},headerTintColor: '#fff', // 导航栏中文字、按钮、图标的颜色headerTitleStyle: { // 导航栏标题样式fontWeight: 'bold',},}}><Stack.Screen name="index" options={{ title: '首页' }} /><Stack.Screenname="courses/[id]"options={({ route }) => ({title: route.params?.title || '课程页', // 使用 params 中的 title,如果没有则显示默认值})}/></Stack>);
}
name
的值就和首页文件的路径对应。- 因为首页文件和布局文件同级,所以直接写
index
就行。
配置自定义导航栏
_layout.js
:
import { Link, Stack } from 'expo-router';
import { Image, StyleSheet, TouchableOpacity } from 'react-native'
import SimpleLineIcons from '@expo/vector-icons/SimpleLineIcons';/*** 导航栏 Logo 组件*/
function LogoTitle() {return <Image style={style.logo} contentFit="contain" source={require('../assets/logo-light.png')}/>
}/*** 导航栏按钮组件* @param props*/
function HeaderButton({ href, ...rest }) {return (<Link href={href} asChild><TouchableOpacity><SimpleLineIcons size={20} color="#1f99b0" {...rest} /></TouchableOpacity></Link>)
}export default function Layout() {return (<StackscreenOptions={{title: '', // 默认标题为空headerTitleAlign: 'center', // 安卓标题栏居中animation: 'slide_from_right', // 安卓使用左右切屏headerTintColor: '#1f99b0', // 导航栏中文字、按钮、图标的颜色headerTitleStyle: { // 标题组件的样式fontWeight: '400',color: '#2A2929',fontSize: 16,},headerBackButtonDisplayMode: 'minimal', // 设置返回按钮只显示箭头,不显示文字}}><Stack.Screenname="index"options={{headerTitle: props => <LogoTitle {...props} />,headerLeft: () => <HeaderButton name="bell" href="/articles" style={style.headerLeft} />,headerRight: () => (<><HeaderButton name="magnifier" href="/search" style={style.headerRight} /><HeaderButton name="options" href="/settings" style={style.headerRight} /></>),}}/><Stack.Screenname="courses/[id]"options={({ route }) => ({title: route.params?.title || '课程页', // 使用 params 中的 title,如果没有则显示默认值})}/></Stack>);
}const style = StyleSheet.create({logo: {width: 130,height: 30,},headerLeft: {marginLeft: 15,},headerRight: {marginRight: 15,},
});