切换屏幕时白色背景闪烁-React-Navigation v5

时间:2020-01-24 17:06:31

标签: react-native react-navigation react-navigation-stack

我正在将RN项目版本4迁移到5。

切换屏幕时出现白色背景闪烁的问题。 在v4中,这是通过在cardStyle: { backgroundColor: material.containerBgColor }选项中设置StackNavigation来解决的。

但是在v5中,我无法使用相同的方法对其进行修复:

<Stack.Navigator cardStyle={{ backgroundColor: material.containerBgColor }} ...>

白色闪光灯又回来了。知道如何解决吗?谢谢。

更新: 导航的结构可能很重要:

const AppTabNavigator = () => (
  <Tab.Navigator>
    <Tab.Screen name="Home" component={Home} />
    <Stack.Screen name="ScreenD" component={ScreenD} />
    <Stack.Screen name="ScreenE" component={ScreenE} />
    <Stack.Screen name="ScreenF" component={ScreenF} />
  </Tab.Navigator>
)
...
  <Stack.Navigator
    ...
    cardStyle={{ backgroundColor: material.containerBgColor }}
  >
    <Stack.Screen name="Home" component={AppTabNavigator} />
    <Stack.Screen name="ScreenA" component={ScreenA} />
    <Stack.Screen name="ScreenB" component={ScreenB} />
    <Stack.Screen name="ScreenC" component={ScreenC} />
  </Stack.Navigator>

从ScreenD转到ScreenE会出现闪烁问题。我不确定其他屏幕,因为它们不发出任何网络请求/异步内容。

12 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,并投入了调查。似乎是屏幕脱离引起了。我发现了一些方法。您可以根据需要选择一种。它们是:

  1. 您可以使用与屏幕相同的背景色来指定导航器的视图包装:

    |^~\&||||^
  2. 您还可以在堆栈视图配置中将屏幕模式指定为<View style={{ flex: 1, backgroundColor: '#YOUR_SCREEN_COLOR' }}> // It could be your NavigationContainer or your StackNavigator depends on your goals <Navigator /> </View> ,这样可以防止屏幕像以下那样分离:

    modal
  3. 您可以使用<StackNavigator.Navigator mode="modal"> {/*.... Your stack screens ... */} </StackNavigator.Navigator> 属性在screenOptions中添加自定义叠加层:

    cardOverlay

    参考:https://reactnavigation.org/docs/stack-navigator/#cardoverlay

  4. 您可以使用cardOverlay: () => ( <View style={{ flex: 1, backgroundColor: '#YOUR_COLOR', }} />)

    这使您可以自定义在屏幕之间导航时的动画过渡。

    以下是原始文档中的摘录:

    cardStyleInterpolator
    const forFade = ({ current, closing }) => ({
      cardStyle: {
        opacity: current.progress,
      },
    });
    

    当添加或删除屏幕时,Stack Navigator会显示各种选项来配置过渡动画。

    参考:https://reactnavigation.org/docs/stack-navigator/#animation-related-options

答案 1 :(得分:3)

我还在v5中使用StackNavigator,但是没有一个答案对我有用。这就是我解决问题的方式:

const navigatorOptions = {
  headerShown: false,
  cardStyle: { backgroundColor: 'transparent' },
  cardStyleInterpolator: ({ current: { progress } }) => ({
    cardStyle: {
      opacity: progress.interpolate({
        inputRange: [0, 1],
        outputRange: [0, 1],
      }),
    },
    overlayStyle: {
      opacity: progress.interpolate({
        inputRange: [0, 1],
        outputRange: [0, 0.5],
        extrapolate: 'clamp',
      }),
    },
  }),
}
 
...

<AppStack.Navigator
  screenOptions={navigatorOptions}
  mode="modal"
>
...

我在这里找到了解决方法:https://reactnavigation.org/docs/stack-navigator#transparent-modals

答案 2 :(得分:3)

对我来说,解决此问题的一个简单方法是像这样在Tab导航器中设置"dependsOn": [ "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]" ]

sceneContainerStyle

答案 3 :(得分:2)

我通过禁用Tab导航器的sceneAnimationEnabled解决了该问题。

<Tab.Navigator
  sceneAnimationEnabled={false}>
  {...}
</Tab.Navigator>

答案 4 :(得分:2)

使用DarkTheme作为导航容器修复了该问题

import { NavigationContainer, DarkTheme } from '@react-navigation/native';

return (
    <NavigationContainer theme={DarkTheme}>
       {children}
    </NavigationContainer>

答案 5 :(得分:1)

cardStyle是屏幕上的选项,而不是导航器。

<Stack.Navigator screenOptions={{ cardStyle: backgroundColor: material.containerBgColor }}>
  {/* ... */}
</Stack.Navigator>

<Stack.Navigator>
  <Stack.Screen
    name="Home"
    component={AppTabNavigator}
    options={{ cardStyle: backgroundColor: material.containerBgColor }}
  />
  {/* ... */}
</Stack.Navigator>

参考:https://reactnavigation.org/docs/en/next/stack-navigator.html#cardstyle

可能更好的方法是使用主题系统传递颜色,而不是为每个导航器指定颜色:https://reactnavigation.org/docs/en/next/themes.html

答案 6 :(得分:1)

const App = () => (
  <View style={styles.appStyle}>
     <Navigation />
  </View>
);
const styles = StyleSheet.create({
  appStyle: { flex: 1, backgroundColor: "#000" }
});

答案 7 :(得分:1)

就我而言,这是由于 NavigationContainer 中 SafeAreaProvider 的默认样式。设置

<SafeAreaProvider style={{ backgroundColor: "black" }}>

成功了。

答案 8 :(得分:0)

我通过在 lazy={false} 组件中设置 <Tabs.Navigator> 解决了这个问题:

<Tabs.Navigator
    lazy={false}
>

答案 9 :(得分:0)

我用这段代码解决了这个问题:你也可以把 cardStyleInterpolator 放在每个 options<Screen> 属性中

const notAnimation = () => ({});

screenOptions={{ cardStyleInterpolator: notAnimation }}>

答案 10 :(得分:0)

我的问题是我在 App.tsx 中启用了 enableScreens()

您有两个选择:

  • 删除 enableScreens() 调用
  • detachPreviousScreen: false 添加到您的导航器的 screenOptions 并将 enableScreens(true) 添加到您的 App.tsx

答案 11 :(得分:0)

我使用了@jul 提供的解决方案

<SafeAreaProvider style={{ backgroundColor: "black" }}>

小的区别是我们的 SafeAreaProvider 在更高的层次上包装了 NavigationContainer

<SafeAreaProvider style={{ backgroundColor: "black" }}>
   ...
   <NavigationContainer />
   ...
</SafeAreaProvider>

作为默认背景色,无需使用原生模块设置根背景色