react-native-dark-mode:基于 React Native 的鸿蒙深色模式适配项目

检测系统深色模式(Dark Mode)的库

Branch3Tags3

react-native-dark-mode

本项目基于 react-native-dark-mode开发。如果在使用过程中有任何问题,欢迎在AtomGit提交Issue,会及时跟进。

项目介绍

@hxa-rn/react-native-dark-mode 用于在 React Native 应用中检测 HarmonyOS 系统的深色或浅色模式,并在模式变化时更新 Context、Hooks、动态值和动态样式。当前版本为 0.2.5。

本包包含 HarmonyOS 原生 TurboModule RNDarkMode。原生侧读取系统颜色模式、提供初始模式与支持状态,并向 JS 层发送模式变化事件;因此它不是 js-only 包。

集成指南

安装 HarmonyOS 适配包:

npm install @hxa-rn/react-native-dark-mode

harmony.alias 为 react-native-dark-mode,业务代码仍使用原包名导入:

import { useDarkMode } from 'react-native-dark-mode';

应用工程需提供以下 peer dependencies:

  • react-native >=0.72
  • react(版本由应用工程提供)

本包包含原生实现,并声明了 RNOH Autolinking 配置;支持 Autolinking 的工程无需手工注册。

使用说明

以下示例根据当前模式切换文字和样式,并允许局部子树固定为深色模式:

import React from 'react';
import { Text, View } from 'react-native';
import {
  DarkModeProvider,
  DynamicStyleSheet,
  DynamicValue,
  useDarkMode,
  useDarkModeContext,
  useDynamicStyleSheet,
  useDynamicValue,
} from 'react-native-dark-mode';

const dynamicStyles = new DynamicStyleSheet({
  container: {
    flex: 1,
    backgroundColor: new DynamicValue('#ffffff', '#000000'),
  },
  text: {
    color: new DynamicValue('#000000', '#ffffff'),
  },
});

function ThemedContent() {
  const mode = useDarkModeContext();
  const isDark = useDarkMode();
  const styles = useDynamicStyleSheet(dynamicStyles);
  const label = useDynamicValue('浅色模式', '深色模式');

  return (
    <View style={styles.container}>
      <Text style={styles.text}>
        {label}:{mode}(isDark={String(isDark)})
      </Text>
    </View>
  );
}

export default function App() {
  return (
    <DarkModeProvider>
      <ThemedContent />
      <DarkModeProvider mode="dark">
        <ThemedContent />
      </DarkModeProvider>
    </DarkModeProvider>
  );
}

可通过 eventEmitter 直接监听系统模式变化:

import { eventEmitter } from 'react-native-dark-mode';

const handler = (mode: 'light' | 'dark') => {
  console.info(`current mode: ${mode}`);
};

eventEmitter.on('currentModeChanged', handler);
eventEmitter.off('currentModeChanged', handler);

接口文档

模式常量与事件

API 调用形式或类型 功能与语义
Mode 'light' | 'dark' 公开的模式类型。
initialMode Mode TurboModule 创建时读取的系统模式快照;运行期间的变化不会改写该常量。
supportsDarkMode boolean 表示系统是否支持深色模式;HarmonyOS 实现固定返回 true。
eventEmitter DarkModeEventEmitter 通过 on、once、off 等事件方法订阅或取消订阅 currentModeChanged;事件回调接收一个 Mode 字符串,currentMode 保存最近模式。

Context 与 Hooks

API 参数 返回值与语义
DarkModeContext React Context 默认值为内部标记 current,通常应通过 DarkModeProvider 和 Hooks 使用。
DarkModeProvider { mode?: Mode; children: ReactNode } 返回 Provider 元素;未传 mode 时跟随系统,传入后固定子树模式。
useDarkModeContext() 无 返回当前 Context 的 Mode。
useDarkMode() 无 当前模式为 dark 时返回 true,否则返回 false。
useDynamicStyleSheet(sheet) DynamicStyleSheet<T> 返回当前模式对应的 NormalizeStyles<T>。
useDynamicValue(value) DynamicValue<T> 返回当前模式对应的 T。
useDynamicValue(light, dark) 两个 T 值 浅色模式返回 light,深色模式返回 dark。

动态值、样式与公开类型

API 构造参数或类型 功能与语义
new DynamicValue(light, dark) 两个 T 值 保存 .light 与 .dark 两个只读值。
new DynamicStyleSheet(styles) 可在样式属性中使用 DynamicValue 的对象 构造时生成 .light 与 .dark 两套 React Native 静态样式。
NormalizeStyles<T> TypeScript 类型 表示移除样式中 DynamicValue 包装后的静态样式结果。
DynamicViewStyle TypeScript 类型 支持 DynamicValue 的 ViewStyle。
DynamicTextStyle TypeScript 类型 支持 DynamicValue 的 TextStyle。
DynamicImageStyle TypeScript 类型 支持 DynamicValue 的 ImageStyle。

快速验证(运行 Example)

前置条件

依赖 版本要求
Node.js >= 18
DevEco Studio 5.0+ / 6.0+
HarmonyOS SDK API 12+

运行步骤

1. 克隆仓库

git clone https://gitcode.com/hxa-rn/react-native-dark-mode.git
cd react-native-dark-mode
git checkout main

2. 安装仓库开发依赖

npm install --legacy-peer-deps

Example 已改为从 npm 公仓安装 @hxa-rn/react-native-dark-mode@0.2.5,不再使用本地 file:../xxx.tgz,运行 Example 不必再执行 npm pack。

3. 进入 example 目录,安装依赖

cd example
npm install --legacy-peer-deps

4. 生成 JS Bundle

npm run dev

产物:harmony/entry/src/main/resources/rawfile/bundle.harmony.js

5. 用 DevEco Studio 打开鸿蒙工程

  • 打开 DevEco Studio
  • 选择 example/harmony 目录
  • 等待 Sync 完成

6. 编译并运行 HAP

在 DevEco Studio 中点击运行按钮,将 HAP 安装到设备/模拟器。

注意:Example 中已预置插件依赖和 Package 注册,无需手动配置 Link。

约束与限制

  • 兼容性:react-native peer dependency 要求 >=0.72;两个 Demo 当前均使用 React Native 0.72.5 和 RNOH 0.72.139。两个 Demo 的 compatibleSdkVersion 均为 5.0.1(13),即 HarmonyOS API 13。
  • 运行环境:包声明 Node.js >=18;实际应用工程还需满足自身工具链要求。
  • 权限:插件 module.json5 的 requestPermissions 为空,无额外系统权限。
  • 平台差异:HarmonyOS 的 supportsDarkMode 固定为 true;系统颜色模式未设置或不可用时按浅色模式处理。
  • 事件行为:currentModeChanged 的载荷为 'light' 或 'dark';相同模式不会重复发送,应用回到前台时会补检系统模式。
  • 初始值限制:initialMode 仅代表模块创建时的模式,持续响应变化应使用 Hooks、Context 或 eventEmitter。

开源license

本项目基于 MIT 协议,详见 LICENSE 文件。

问题反馈渠道

使用过程中如有问题,欢迎通过 AtomGit 社区提交 Issue,也可在以下 GitCode 仓库反馈:

Introduction

检测系统深色模式(Dark Mode)的库

Customize your domain