React Navigation 默认背景颜色

33

我正在使用 react-navigation 和 stack-navigator 来管理我的屏幕。

我使用的平台:

  • Android
  • React Native: 0.47.1
  • React Navigation: 1.0.0-beta.11
  • 模拟器和设备

我有一个屏幕,它作为模态表单,但实际上它是一个全屏幕。为什么重要的是"作为模态表单"的部分?因为它是一种带有一些选项和透明背景颜色的模态菜单

这是我期望的结果:

enter image description here

但我得到的是这个:

enter image description here

正如你所看到的,在第二个示例中,背景颜色完全被替换,或者先前加载的组件被卸载,所以我想要实现的效果丢失了。 我的想法是能够像任何其他屏幕一样导航到这个屏幕。

如果使用 react-navigation 无法实现,我该如何做?

由于这个组件是一个跨应用程序组件并封装了很多机制和逻辑,因此它执行操作(redux)。这就是为什么我不能将其用作PureComponent,而是依靠使用此组件的组件。至少将此组件设置为 PureComponent 将强制我在许多其他组件中复制许多机制和逻辑。

为了让问题简洁明了,并避免让问题变得巨大,两个屏幕具有完全相同的样式,但通过StackNavigation推送的屏幕将替换backgroundColor,或卸载前一个屏幕。

这就是我目前的情况:

//PlaylistSelector.js
render() {
  //Just a full size empty screen to check and avoid bugs
  //Using red instead of transparent, works

  return (
    <View style={{ flex: 1, backgroundColor: 'transparent' }}>
    </View>
  );
}

//Navigator.js
import { StackNavigator } from 'react-navigation';

import Album from './Album'; //This is the screen I expect to keep at the background
import PlaylistSelector from './PlaylistSelector';

const AppNavigator = StackNavigator(
    {
        ...moreScreens,
        Album: { screen: Album },
        PlaylistSelector: {
            screen: PlaylistSelector,
            navigationOptions: {
                style: { backgroundColor: 'red' } //Does not work, red is just to ilustrate, should be transparent,
                cardStyle: { //Does not work,
                    backgroundColor: 'transparent',
                },
                bodyStyle: { //Does not work,
                    backgroundColor: 'transparent',
                },
            }
        }
    },
    {
        initialRouteName: 'Splash',
        headerMode: 'none',
        cardStyle: { //Does not work
            backgroundColor: 'transparent',
        },
        transitionConfig: (): Object => ({ //Does not work
            containerStyle: {
                backgroundColor: 'transparent',
            },
        }),
    }
);

export default AppNavigator;

有解决方法吗?我现在遇到了这个问题。 - user5283119
我不得不创建自己的模态并特别为此案例进行管理。我还没有回到这个问题,所以我不知道它是否已经解决。 - Facundo La Rocca
1
我刚刚成功解决了这个问题,使用containerStyle:{backgroundColor: 'transparent'}。原来我正在编辑错误的stackNavigator,因为我使用了嵌套的stackNavigator。 - user5283119
9个回答

93

这在最新的React Navigation版本中有了很大的改变。请参见{{链接}}。

https://reactnavigation.org/docs/themes/

例如
import * as React from 'react';
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';

const MyTheme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    background: 'red'
  },
};

export default function App() {
  return (
    <NavigationContainer theme={MyTheme}>{/* content */}</NavigationContainer>
  );
}

1
完美适用于React-Native 5.0。 - Tushar Pandey
2
我的应用程序使用深色调,但在屏幕转换期间出现了白色闪烁。使用这个方法解决了白色闪烁问题,非常感谢。 - Ibrahim Azhar Armar

23

react-navigation v6.x 中有一个解决方案。

在堆栈导航器的 screenOptions 属性中设置 cardStyle: {backgroundColor: 'transparent'} 对我并没有起作用。

但是,在 这个 Github 问题页面 的帮助下,我找到了一个解决方案,为我们的 NavigatorContainer 设置默认的背景颜色:

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

...

const navTheme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    background: 'transparent',
  },
};

...

return (
    <NavigationContainer
      theme={navTheme}
...

在那里,我们可以将 'transparent' 更改为任何我们想要的内容。


6

使用react-navigation v3.x,您可以使用transparentCard属性:

const MainNavigator = createStackNavigator(
  {
    BottomTabs: {
      screen: BottomTabsStack,
    },
    Modal: {
      screen: ModalScreen,
    }
  },
  {
    headerMode: 'none',
    mode: 'modal',
    transparentCard: true,
    cardStyle: { opacity: 1 } //This prop is necessary for eventually issue.
  }
);

以下是完整的示例:

您可以在以下链接中找到完整的示例:

https://snack.expo.io/@cristiankmb/stacks-in-tabs-with-header-options-with-modal


这应该被标记为正确答案。这个是ReactNavigation的Modal的Snack演示文档。我尝试应用上述配置,它确实起作用了。 - samthui7

1

添加不透明度:

cardStyle: {
  backgroundColor: "transparent",
  opacity: 1
}

1

对我来说,最直接的方法是将headerBackground设置在screenOptions中:

    <Stack.Navigator
      headerMode={"float"}
      screenOptions={{
        headerBackground: () => <View style={{flex: 1, backgroundColor: themeContext.background}} />,
        backgroundColor: themeContext.background
      }}
    >

这个方法无法处理透明的标题栏,这也可能是你来到这里的原因。在这种情况下,只需将整个应用程序容器包装在一个 View 中,像这样。

export default function App() {
  return (
    <View style={{flex: 1, backgroundColor: 'red'}}>
      <NavigationContainer linking={linkingConfig}>
        <StatusBar />
        <ApolloProvider client={client}>
          <Provider store={store}>
            <Navigator />
          </Provider>
        </ApolloProvider>
      </NavigationContainer>
    </View>
  )
}

显然,你想将它提取为自己的(已样式化的)组件 :)

如果你使用的是Expo,并且没有单独的暗色主题,那么你可以在app.json中简单地设置backgroundColor


0

自从 react-navigation@2.17.0 版本,就增加了一个配置选项transparentCard,使得这个操作成为可能。

const RootNavigator = createStackNavigator(
  {
    App,
    YourModal,
  },
  {
    headerMode: 'none',
    mode: 'modal',
    transparentCard: true,
  },
);

这不会为您模糊背景,它只会使其透明。要正确地模糊它,您需要做类似于this的事情。确保您将背景从屏幕顶部以上开始,因为卡片将从底部动画进入,您可能希望屏幕逐渐模糊,而不是在动画进入时透明度具有锐利的边缘。


0

无论是模态表单还是非模态表单,StackNavigator都会卸载前一个屏幕。 - Facundo La Rocca
“StackNavigator卸载前一个屏幕”是什么意思?该链接不是关于模态导航,而是普通的Modal。 - Bright Lee
使用您提出的方式来使用 Modal 意味着每次需要时都必须手动渲染它,而且由于它是跨应用程序屏幕,我希望像任何其他屏幕一样导航它 (this.props.navigation.navigate('ModalScreen', {...})),并将其连接到 redux store。为此,无论是 Modal 还是 View,由于上一个屏幕已卸载,结果始终是我上面描述的内容。 - Facundo La Rocca
啊,我仔细再看了你的问题,我明白了。对此我感到抱歉。 - Bright Lee

0

这种方法对我有效:

const MyDrawerNavigator = createStackNavigator(
    {
        screen1: {
            screen: screen1,
        },
        screen2: {
            screen: screen2,
        },
    },
    {
        navigationOptions: () => ({
            cardStyle: {
                backgroundColor: "rgba(0,0,0,0.5)",
            },
        }),
    }

);

0
您可以通过在“选项”中设置“contentStyle”属性并选择您喜欢的颜色来实现此目的。例如,请参见以下内容 -
<NavigationContainer >
  <Stack.Navigator>
    <Stack.Screen
      name="Home"
      component={HomeScreen}
      options={{ contentStyle:{backgroundColor: "white",} }}
    />

上述代码将屏幕的背景颜色设置为“白色”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接