Expo Router v3 带有堆栈、搜索和大标题的选项卡导航

问题描述 投票:0回答:1

我试图模仿苹果联系人导航标题,使用大标题进行搜索,但仅在主屏幕上进行。所有其他选项卡都应该有自己的设置,例如没有不同的标题,有时甚至隐藏导航栏。我认为我已经奠定了坚实的基础,但搜索和大标题设置没有任何效果。可复制的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 的用法不一致。我的结构正确还是我做错了什么?任何帮助或见解将不胜感激!

ios typescript react-native expo react-navigation
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.