react native的expo router安卓下modal不生效的解法

最近跟着教程学react native,教程使用的是iOS,而我在windows下开发用的安卓真机,除了一些样式上的区别大体的功能差不多.
但路由的modal显示不一样感觉观感差的有点多.
这是因为安卓原生是没有iOS那种modal的路由的,expo router使用的是react navigationnative stack,这个设置项在安卓下没有效果.

解法很简单,在github的issue中有人提到过了,其实expo router的老的文档里也有提到,新的文档没这部分内容了.
stack
代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import {
// Import the creation function
createStackNavigator,
// Import the types
StackNavigationOptions,
} from "@react-navigation/stack";

import { withLayoutContext } from "expo-router";

const { Navigator } = createStackNavigator();

// This can be used like `<CustomStack />`
export const CustomStack = withLayoutContext<
StackNavigationOptions,
typeof Navigator
>(Navigator);

但这个代码在现在版本的expo里不能运行,会报类型错误.

在一个github的讨论中有新的代码:
presentation: ‘modal’ does’t work for Stack in Android
如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Stack, withLayoutContext } from "expo-router";
import {
createStackNavigator,
StackNavigationEventMap,
StackNavigationOptions,
TransitionPresets,
} from "@react-navigation/stack";
import { ParamListBase, StackNavigationState } from "@react-navigation/native";

const { Navigator } = createStackNavigator();

export const JsStack = withLayoutContext<
StackNavigationOptions,
typeof Navigator,
StackNavigationState<ParamListBase>,
StackNavigationEventMap
>(Navigator);

修改_layout.tsx:

1
2
3
4
5
6
7
8
9
10
11
<JsStack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<JsStack.Screen
name="filters"
options={{
...TransitionPresets.ModalPresentationIOS,
presentation: "modal",
gestureEnabled: true,
}}
/>
</JsStack>

在使用过程中我发现他会和zeego冲突,导致zeego功能不可用.
解决方法是在使用到zeego的page里在额外套一个Stack,也就是wrap一个Stack(其他的layout也可以,就是不能直接被JsStack包裹),这样zeego就可以工作了.