【问题标题】:White flickering when transitioning to a new screen and the background is a dark color?切换到新屏幕时白色闪烁且背景为深色?
【发布时间】:2025-12-13 19:40:02
【问题描述】:

我在使用两个不同的导航器从一个屏幕过渡到另一个屏幕时遇到这种情况:前导航和新的 React Navigation .白色闪烁一秒钟(或半秒钟)。寻找解决方案我发现其他导航器也有同样的问题。例如来自 wix 的导航器 HERE。从链接:

好的,问题是,React 样式在导航之后应用 启动,默认情况下背景颜色是白色,所以这是 闪烁效果..

有人遇到同样的问题吗?

【问题讨论】:

标签: react-native react-native-navigation wix-react-native-navigation exponentjs


【解决方案1】:

对我来说,解决方案是设置layout 选项。我正在使用wix-react-native-navigation:

    layout: {
      backgroundColor: "#000",
      componentBackgroundColor: "#000",
    },

【讨论】:

    【解决方案2】:

    我基于scaleFromAndroid创建了一个Typescript cardStyleInterpolator函数,以防止切换屏幕时屏幕周围出现空白。

    此函数在屏幕之间切换时删除opacity: 0 和过渡结束,并在屏幕边框添加overlayStyle

    例子:

    <Stack.Navigator
      screenOptions={{
        headerShown: false, /* Hide the header */
        cardStyleInterpolator: scaleCenterAndroidInterpolator /* Overrides the default cardStyleInterpolator */
      }}>
      ...
    </Stack.Navigator>

        const scaleCenterAndroidInterpolator = ({ 
            current, 
            closing, 
            next 
        }: StackCardInterpolationProps)  => {
    
            const { add, multiply } = Animated;
    
            const handleConditionalScale = (
                condition: Animated.AnimatedInterpolation, 
                main: Animated.AnimatedInterpolation, 
                fallback: Animated.AnimatedInterpolation) => (
                    add(multiply(condition, main), multiply(condition.interpolate({
                        inputRange: [0, 1],
                        outputRange: [1, 0]
                      }), fallback))
                )
    
            const progress: Animated.AnimatedAddition = add(current.progress.interpolate({
                inputRange: [0, 1],
                outputRange: [0, 1],
                extrapolate: 'clamp'
              }), next ? next.progress.interpolate({
                inputRange: [0, 1],
                outputRange: [0, 1],
                extrapolate: 'clamp'
              }) : 0);
    
            const opacity: Animated.AnimatedInterpolation = progress.interpolate({
                inputRange: [0, 0.75, 0.875, 1, 1.0825, 1.2075, 2],
                outputRange: [0, 0, 1, 1, 1, 1, 1]
            });
    
            const scale: Animated.AnimatedAddition = handleConditionalScale(closing, current.progress.interpolate({
                inputRange: [0, 1],
                outputRange: [0.925, 1],
                extrapolate: 'clamp'
              }), progress.interpolate({
                inputRange: [0, 1, 2],
                outputRange: [0.85, 1, 1.075]
              }));
    
            const overlayStyle: { opacity: Animated.AnimatedInterpolation } = {
                opacity: current.progress.interpolate({
                    inputRange: [0, 1],
                    outputRange: [0, 0.5],
                    extrapolate: 'clamp',
                })
            }
    
            return {
                cardStyle: {
                    opacity: opacity,
                    transform: [
                        { scale }
                    ],
                },
                overlayStyle
            }
    
        }

    【讨论】:

      【解决方案3】:

      我知道我在这里发帖的时间很晚,但是如果有人通过这个得到帮助,那将是值得的。

      我也遇到了同样的问题,因为我在项目中使用了深色主题,并且每当导航发生时,白屏都会闪烁几毫秒。

      我通过向 NavigationContainer 主题道具添加相同的主题背景颜色来解决此问题,如下所示

      &lt;NavigationContainer theme ={{colors:{background: /*same background color of your project */}}}&gt; .... &lt;/NavigationContainer&gt;

      这解决了我的问题,希望它也解决其他人的问题。

      谢谢你..

      【讨论】:

        【解决方案4】:

        对于使用 expo 的人,您还需要在您的 app.json 中传递一个 backgroundColor。因此,您应该将其设置为应用配色方案中的某种深色。

        // app.json
        
        {
          "expo": {
            ...
            "backgroundColor": "#1a202c"
          }
        }
        

        【讨论】:

          【解决方案5】:

          我通过在 React-Navigation v5 的 NavigationContainer 中设置属性解决了白色闪烁问题。

          <NavigationContainer theme={{ colors: { background: '#000' } }}>
          {...}
          </NavigationContainer>
          

          当我更新与背景颜色黑色相同的颜色时,它帮助我消除了白色闪烁。

          https://github.com/software-mansion/react-native-screens/issues/380#issuecomment-748038449

          【讨论】:

          • 但是它确实解决了这个问题,它将原本白色的背景默认为黑色。
          • 只花了几个小时,您的解决方案就奏效了。谢谢!
          【解决方案6】:

          对我来说,这成功了:

          cardStyle: { opacity: 1 }
          

          例子:

          const RootNavigator = createStackNavigator({
              Login: { screen: Login },
              Main: { screen: DrawerNavigator }
          },
              {
                  initialRouteName: 'Login',
                  cardStyle: { opacity: 1 } // Prevent white flicker on Android when navigating between screens
              }
          );
          
          export default createAppContainer(RootNavigator);
          

          【讨论】:

          • 您在哪里添加了 cardStyle。 (即)在 navigationOptions 或 defaultNavigationOptions
          • 我编辑了我的答案来举个例子。它不在 navigationOptions 里面。
          • 以上不适用于 iOS。你有针对 iOS 的任何修复吗
          【解决方案7】:

          在使用 DrawerNavigator 和 StackNavigator 时,需要:

          cardStyle: {
              backgroundColor: 'transparent',
          },
          

          需要:

          使用react-native-root-view-background 设置RootViewBackgroundColor('black')

          【讨论】:

            【解决方案8】:

            您可以像这样在导航器中设置背景颜色:

            <
            Navigator style={{flex: 1}} 
              transitionerStyle={{backgroundColor: 'black'}} ...
            

            希望这有帮助-

            【讨论】:

              【解决方案9】:

              我也遇到了同样的问题。在我看来,有两种解决方案。

              • 第一个解决方案来自您共享的link。基本上,您可以为 Navigator 组件添加背景颜色。
              • 我之前应用于我的项目的第二个解决方案不是一个确切的解决方案,而是一种解决方法。我通过将SceneConfigsNavigator.SceneConfigs.FloatFromRight 更改为Navigator.SceneConfigs.PushFromRight,更改了Navigator 组件来回转换屏幕的方式。所以我的Navigator 组件变成了类似的东西;

                        <Navigator
                            ref={(ref) => this._navigator = ref}
                            configureScene={(route) => {
                                return {
                                    ...Navigator.SceneConfigs.PushFromRight,
                                    gestures: {}
                                };
                            }}
                            initialRoute={{
                                id: (Platform.OS === "android" || Platform.OS === "ios") ? 'splashscreen' : 'login',
                                statusBarHidden: true
                            }}
                            renderScene={this.renderScene}
                        />
                

              【讨论】: