文章目录
- 一、Light / Dark Mode 的原理
- 1. 操作系统层
- 2. React Native 如何获取?
- 3. 样式怎么跟着变?
- 二、关键代码示例讲解
- 代码讲解:
- 三、自定义主题
- 四、运行时自动更新
- 五、核心原理一张图
- 组件应用例子
- 最小示例:动态样式
- 按钮的动态样式
- 如何封装一套自定义主题
- 四、如何和 ThemeProvider 配合?
- 小技巧
- 总结
- 总结一句话
这其实是现代移动应用开发中非常常用的功能:自动适配浅色/深色模式(Light / Dark Mode)。
在业内,譬如 React Native + Expo 把这个机制做得非常友好,下面我帮你从原理到代码一步步拆解,让你彻底理解它是如何工作的。
一、Light / Dark Mode 的原理
1. 操作系统层
所有的主流操作系统(Android、iOS、macOS、Windows)都提供了「全局配色方案」设置:
- 浅色(Light)
- 深色(Dark)
当用户在系统里选择了一个模式后,操作系统会把这个偏好传递给应用程序。
2. React Native 如何获取?
React Native 暴露了一个 hook:
const colorScheme = useColorScheme();
这个 hook:
- 自动监听系统主题
- 返回
'light'
、'dark'
或null
例如:
const colorScheme = useColorScheme();
console.log(colorScheme);
// 可能打印:'light' 或 'dark'
一旦系统主题改变(比如用户切换深色模式),React Native 会自动重新渲染你的组件。
3. 样式怎么跟着变?
知道当前主题后,你就可以:
- 切换颜色
- 切换主题对象
- 切换字体或其他样式
Expo Router 的模板里,就是通过 <ThemeProvider>
提供一个全局主题对象:
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
- 当 colorScheme 是
'dark'
,使用DarkTheme
- 当 colorScheme 是
'light'
,使用DefaultTheme
所有内部的组件(如导航、背景色、按钮)就都自动使用对应的颜色配置。
二、关键代码示例讲解
来看你提到的核心代码:
return (<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}><Stack><Stack.Screen name="(tabs)" options={{ headerShown: false }} /><Stack.Screen name="+not-found" /></Stack><StatusBar style="auto" /></ThemeProvider>
);
代码讲解:
useColorScheme()
- 获取系统主题
ThemeProvider
- 提供全局主题对象
- 内部的
Stack
、Tab
、Drawer
会自动根据这个 Theme 渲染样式(背景、字体颜色、分隔线等)
DarkTheme
和 DefaultTheme
-
都是内置的主题对象
-
定义了:
- 主色
- 背景色
- 文本颜色
- 边框色
- 卡片颜色
StatusBar style="auto"
- 自动根据主题切换状态栏字体颜色(黑色/白色)
三、自定义主题
如果你想扩展自己的配色,可以在 themes.ts
文件定义:
export const MyLightTheme = {...DefaultTheme,colors: {...DefaultTheme.colors,primary: '#1e90ff',background: '#ffffff',text: '#333333',},
};export const MyDarkTheme = {...DarkTheme,colors: {...DarkTheme.colors,primary: '#1e90ff',background: '#000000',text: '#ffffff'