颜色主题

编辑

了解如何在应用中支持亮色和暗色模式。


应用通常支持明暗两种颜色模式。下面是一个在 Expo 项目中同时支持这两种模式的示例:

配置

对于 Android 和 iOS 项目,需要额外的配置来支持在明暗模式之间切换。对于 Web,不需要额外的配置。

要配置所支持的外观样式,可以在项目的 userInterfaceStyle 属性中进行设置,位于 应用配置(app config) 中。默认情况下,当你使用 默认模板 创建新项目时,此属性被设置为 automatic

以下是一个配置示例:

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

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

如果该属性缺失,应用将默认使用 light 样式。

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

Terminal
npx expo install expo-system-ui

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

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

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

Terminal
npx expo config --type introspect
使用裸 React Native 应用?

Android

确保在你的 MainActivity(以及任何希望实现此行为的其他活动)中,以及在 AndroidManifest.xml 中,包含 uiMode 标志:

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

MainActivity.java 中实现 onConfigurationChanged 方法:

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 以同时支持明亮模式和暗黑模式。

支持的外观风格

userInterfaceStyle 属性支持以下值:

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

检测配色方案

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

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

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

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

在某些情况下,您会发现以命令方式获取当前颜色方案非常有用,例如使用 Appearance.getColorScheme(),或通过 Appearance.addChangeListener() 监听变化。

附加信息

最小示例

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', }, });

提示

在开发项目时,您可以通过以下快捷方式来更改模拟器或设备的外观:

  • 如果使用 Android 模拟器,您可以运行 adb shell "cmd uimode night yes" 来开启深色模式,且 adb shell "cmd uimode night no" 来关闭深色模式。
  • 如果使用实体 Android 设备或 Android 模拟器,您可以在设备设置中切换系统的深色模式设置。
  • 如果在本地使用 iOS 模拟器,您可以使用 Cmd ⌘ + Shift + a 快捷方式在明暗模式之间切换。