我试图模仿苹果联系人导航标题,使用大标题进行搜索,但仅在主屏幕上进行。所有其他选项卡都应该有自己的设置,例如没有不同的标题,有时甚至隐藏导航栏。我认为我已经奠定了坚实的基础,但搜索和大标题设置没有任何效果。可复制的repo在这里。
一般来说,我的结构是一个指向
/apps/_layout.tsx
: 的入口点
import { Stack } from 'expo-router';
export default function Layout() {
return (
<Stack screenOptions={{ headerShown: false }}>
<Stack.Screen name="(tabs)" />
</Stack>
);
}
根布局指向第一个堆栈,它是一个包含主应用程序的选项卡视图,位于
/apps/(tabs)/_layout.tsx
,如下所示:
import { BlurView } from 'expo-blur';
import { Tabs } from 'expo-router';
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function TabsLayout() {
return (
<SafeAreaProvider>
<Tabs
screenOptions={{
tabBarStyle: { position: 'absolute', elevation: 0 },
tabBarBackground: () =>
<BlurView tint="prominent" intensity={100} style={StyleSheet.absoluteFill} />
}}>
<Tabs.Screen name="index" />
<Tabs.Screen name="tab2" />
</Tabs>
</SafeAreaProvider>
);
}
第一个选项卡是索引页,位于
/apps/(tabs)/index.tsx
,如下:
import { BottomTabBarHeightContext, useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
import { useHeaderHeight } from '@react-navigation/elements';
import { BlurView } from 'expo-blur';
import { Stack } from 'expo-router';
import { ScrollView } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Text, StyleSheet } from 'react-native';
export default function Home() {
const items = Array.from({ length: 60 }, (_, index) => index);
const headerHeight = useHeaderHeight();
const bottomTabBarHeight = useBottomTabBarHeight();
return (
<ScrollView style={{ flex: 1, backgroundColor: 'blue' }}>
<Stack.Screen
options={{
headerShown: true,
headerTransparent: true,
headerBackground: () =>
<BlurView tint="prominent" intensity={100} style={StyleSheet.absoluteFill} />
}}
/>
<SafeAreaView
edges={['left', 'right']}
style={{
flex: 1,
backgroundColor: 'green',
paddingTop: headerHeight,
paddingBottom: bottomTabBarHeight
}}
>
{items.map((item, index) => (
<Text key={index} style={{...}}>{`Item ${item}`}</Text>
))}
</SafeAreaView>
</ScrollView>
);
}
这让我有了一个良好的原生基础,内容在标题和底部选项卡下延伸,内容在其下滚动。
它甚至可以横向工作,这是一个好兆头:
现在我正在尝试将标题变大,并在导航栏中添加搜索栏,就像 Apple Contact 应用程序一样:
我尝试在不同区域添加以下内容,但没有效果:
headerLargeTitle: true,
headerSearchBarOptions: {
placeholder: 'Search'
}
文档非常简单,示例已经过时或没有使用基于文件的Expo Router v3。它与 React Navigation 不同,因此那里的文档与 Expo Router 的用法不一致。我的结构正确还是我做错了什么?任何帮助或见解将不胜感激!
Expo Router 似乎有局限性,因为它是新的 - 至少,有关它的文档不完整。为了正确实现您想要做的事情,您需要翻转结构,使堆栈位于选项卡中,而不是带有选项卡的堆栈:
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator
screenOptions={{
headerShown: false,
...(Platform.OS === 'ios'
? {
tabBarStyle: { position: 'absolute', elevation: 0 },
tabBarBackground: () => (
<BlurView tint="prominent" intensity={100} style={StyleSheet.absoluteFill} />
)
}
: undefined)
}}
>
<Tab.Screen name="HomeTab" component={HomeStack} />
<Tab.Screen name="SettingsTab" component={SettingsStack} />
<Tab.Screen name="MoreTab" component={MoreStack} />
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
const Stack = createNativeStackNavigator();
export function Home({ navigation }: NativeStackScreenProps<ParamListBase>) {
const data = Array.from({ length: 50 });
useLayoutEffect(() => {
navigation.setOptions({
headerSearchBarOptions: {
onChangeText: (text) => console.log(text)
}
});
}, [navigation]);
return (
<View style={{ flex: 1, backgroundColor: 'yellow' }}>
<Text>Home screen</Text>
<Button title="Go to Details" onPress={() => navigation.navigate('Details')} />
{data.map((_, index) => (
<Text key={index} style={{ padding: 10, fontSize: 18, fontWeight: 'bold', color: 'blue' }}>
Item {index + 1}
</Text>
))}
</View>
);
}
export function HomeStack() {
return (
<Stack.Navigator
screenOptions={{
headerTransparent: Platform.OS === 'ios',
headerBlurEffect: 'systemThickMaterial'
}}
>
<Stack.Screen name="Home" component={withScrollStackView(Home)} options={{ headerLargeTitle: true }} />
<Stack.Screen name="Details" component={withScrollStackView(Details)} />
</Stack.Navigator>
);
}
export default function Details() {
return (
<View style={{ flex: 1, backgroundColor: 'yellow' }}>
<Text>Details screen</Text>
</View>
);
}
更多详细信息可以直接在 React Navigation 文档中找到,该文档是 Expo Router 的子集:https://reactnavigation.org/docs/tab-based-navigation#a-stack-navigator-for-each-tab