颜色主题

了解如何在你的应用中支持浅色和夜间模式。


应用通常支持明亮模式和黑夜间模式。下面是一个在 Expo 项目中同时支持这两种模式的示例:

🌐 It's common for apps to support light and dark color schemes. Here is an example of how supporting both modes looks in an Expo project:

配置

🌐 Configuration

信息 对于 Android 和 iOS 项目,需要额外配置以支持在浅色模式和夜间模式之间切换。对于网页,无需额外配置。

要配置支持的外观样式,你可以在项目的应用配置中使用 userInterfaceStyle 属性。默认情况下,当使用默认模板创建新项目时,该属性设置为 automatic

🌐 To configure supported appearance styles, you can use the userInterfaceStyle property in your project's app config. By default, this property is set to automatic when you create a new project with the default template.

这是一个配置示例:

🌐 Here is an example configuration:

app.json
{ "expo": { "userInterfaceStyle": "automatic" } }

你也可以通过将 android.userInterfaceStyleios.userInterfaceStyle 设置为首选值,为特定平台配置 userInterfaceStyle 属性。

🌐 You can also configure userInterfaceStyle property for a specific platforms by setting either android.userInterfaceStyle or ios.userInterfaceStyle to the preferred value.

信息 如果缺少此属性,应用将默认为 light 风格。

当你创建开发版本时,必须安装 expo-system-ui 以支持 Android 的外观样式。否则,userInterfaceStyle 属性将被忽略。

🌐 When you are creating a development build, you have to install expo-system-ui to support the appearance styles for Android. Otherwise, the userInterfaceStyle property is ignored.

Terminal
npx expo install expo-system-ui

如果项目配置错误且未安装 expo-system-ui,终端将显示以下警告:

🌐 If the project is misconfigured and doesn't have expo-system-ui installed, the following warning will be shown in the terminal:

Terminal
» android: userInterfaceStyle: Install expo-system-ui in your project to enable this feature.

还可以使用以下命令检查项目是否配置错误:

🌐 You can also use the following command to check if the project is misconfigured:

Terminal
npx expo config --type introspect
使用原生 React Native 应用吗?

安卓

🌐 Android

确保在 AndroidManifest.xml 中的 MainActivity(以及希望此行为生效的其他活动)上存在 uiMode 标志:

🌐 Ensure that the uiMode flag is present on your MainActivity (and any other activities where this behavior is desired) in AndroidManifest.xml:

<activity android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode">

MainActivity.java 中实现 onConfigurationChanged 方法:

🌐 Implement the onConfigurationChanged method in MainActivity.java:

import android.content.Intent; import android.content.res.Configuration; public class MainActivity extends ReactActivity { %%placeholder-start%%... %%placeholder-end%% @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Intent intent = new Intent("onConfigurationChanged"); intent.putExtra("newConfig", newConfig); sendBroadcast(intent); } %%placeholder-start%%... %%placeholder-end%% }

iOS

你可以在应用的 Info.plist 中使用 UIUserInterfaceStyle 键来配置支持的样式。使用 Automatic 可以同时支持浅色和夜间模式。

🌐 You can configure supported styles with the UIUserInterfaceStyle key in your app Info.plist. Use Automatic to support both light and dark modes.

支持的外观样式

🌐 Supported appearance styles

userInterfaceStyle 属性支持以下值:

🌐 The userInterfaceStyle property supports the following values:

  • automatic:遵循系统外观设置,并在用户进行任何更改时发出通知。
  • light:将应用限制为仅支持浅色主题。
  • dark:将应用限制为仅支持深色主题。

检测配色方案

🌐 Detect the color scheme

要检测项目中的配色方案,请使用 react-native 中的 AppearanceuseColorScheme

🌐 To detect the color scheme in your project, use Appearance or useColorScheme from react-native:

app/index.tsx
import { Appearance, useColorScheme } from 'react-native';

然后,你可以像下面这样使用 useColorScheme() 钩子:

🌐 Then, you can use useColorScheme() hook as shown below:

app/index.tsx
function MyComponent() { let colorScheme = useColorScheme(); if (colorScheme === 'dark') { // render some dark thing } else { // render some light thing } }

在某些情况下,你会发现使用 Appearance.getColorScheme() 获取当前配色方案或使用 Appearance.addChangeListener() 监听变化` 会很有帮助。

🌐 In some cases, you will find it helpful to get the current color scheme imperatively with Appearance.getColorScheme() or listen to changes with Appearance.addChangeListener().

附加信息

🌐 Additional information

最小的例子

🌐 Minimal example

useColorScheme example
import { Text, StyleSheet, View, useColorScheme } from 'react-native'; import { StatusBar } from 'expo-status-bar'; export default function App() { const colorScheme = useColorScheme(); const themeTextStyle = colorScheme === 'light' ? styles.lightThemeText : styles.darkThemeText; const themeContainerStyle = colorScheme === 'light' ? styles.lightContainer : styles.darkContainer; return ( <View style={[styles.container, themeContainerStyle]}> <Text style={[styles.text, themeTextStyle]}>Color scheme: {colorScheme}</Text> <StatusBar /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, text: { fontSize: 20, }, lightContainer: { backgroundColor: '#d0d0c0', }, darkContainer: { backgroundColor: '#242c40', }, lightThemeText: { color: '#242c40', }, darkThemeText: { color: '#d0d0c0', }, });

提示

🌐 Tips

在开发项目时,你可以使用以下快捷键更改模拟器或设备的外观:

🌐 While you are developing your project, you can change your simulator's or device's appearance by using the following shortcuts:

  • 如果使用 Android 模拟器,你可以运行 adb shell "cmd uimode night yes" 来启用夜间模式,运行 adb shell "cmd uimode night no" 来禁用夜间模式。
  • 如果使用实体 Android 设备或 Android 模拟器,可以在设备的设置中切换系统的夜间模式设置。
  • 如果在本地使用 iOS 模拟器,可以使用 Cmd ⌘ + Shift + a 快捷键在浅色和夜间模式之间切换。