rntpc_react-native-bootsplash:基于 react-native-bootsplash 的 OpenHarmony 适配版,启动屏(Boot Splash)显示与隐藏控制

基于 react-native-bootsplash 的 OpenHarmony 适配版,启动屏(Boot Splash)显示与隐藏控制

分支4Tags3
当前项目代码仓暂无内容

文档模板:v0.4.1

react-native-bootsplash

支持的平台 许可证

三方库名称 三方库版本 发布信息 支持RN版本 自动链接 编译API版本 社区基线版本 npm地址
@react-native-ohos/react-native-bootsplash ~6.4.0 (开发中) Gitcode 发布 0.82 API12+ 6.3.11 Npm 地址
@react-native-ohos/react-native-bootsplash ~6.3.5 Gitcode 发布 0.77 API12+ 6.3.4 Npm 地址
@react-native-ohos/react-native-bootsplash ~6.1.2 Gitcode 发布 0.72 API12+ 6.1.1 Npm 地址
@react-native-oh-tpl/react-native-bootsplash <= 6.1.1-0.0.3@已废弃 Github 发布(已废弃) 0.72 API12+ 6.1.1 Npm 地址

简介

react-native-bootsplash 库用于 React Native。
react-native-bootsplash 是一个启动屏(Splash Screen)库,可在应用启动时展示启动屏,并提供隐藏启动屏、查询可见状态及自定义隐藏动画等能力。

下载安装

进入到工程目录并输入以下命令:

npm

npm install @react-native-ohos/react-native-bootsplash

纱线

yarn add @react-native-ohos/react-native-bootsplash

生成配置文件

为了加快设置速度,我们提供了一个CLI来自动生成配置、创建Android Drawable XML文件、iOS Storyboard文件和HarmonyOS Resources文件

$ npx react-native generate-bootsplash --help
# --- or ---
$ yarn react-native generate-bootsplash --help

该命令可以使用多个参数:

Usage: react-native generate-bootsplash [options] <logo>

Generate a launch screen using a logo file path (PNG or SVG)

Options:
  --project-type <string>     Project type ("detect", "bare" or "expo") (default: "detect")
  --platforms <list>          Platforms to generate for, separated by a comma (default: "android,ios,web,harmony")
  --background <string>       Background color (in hexadecimal format) (default: "#fff")
  --logo-width <number>       Logo width at @1x (in dp - we recommend approximately ~100) (default: 100)
  --assets-output <string>    Assets output directory path (default: "assets/bootsplash")
  --flavor <string>           Android flavor build variant (where your resource directory is) (default: "main")
  --html <string>             HTML template file path (your web app entry point) (default: "public/index.html")
  --license-key <string>      License key to enable brand and dark mode assets generation
  --brand <string>            Brand file path (PNG or SVG)
  --brand-width <number>      Brand width at @1x (in dp - we recommend approximately ~80) (default: 80)
  --dark-background <string>  [dark mode] Background color (in hexadecimal format)
  --dark-logo <string>        [dark mode] Logo file path (PNG or SVG)
  --dark-brand <string>       [dark mode] Brand file path (PNG or SVG)
  -h, --help                  display help for command

命令用法示例:

# Without license key
npx react-native generate-bootsplash svgs/light-logo.svg

命令执行后将创建以下文件:

# Without license key
android/app/src/main/res/drawable-mdpi/bootsplash_logo.png
android/app/src/main/res/drawable-hdpi/bootsplash_logo.png
android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png
android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png
android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png
android/app/src/main/AndroidManifest.xml
android/app/src/main/res/values/colors.xml
android/app/src/main/res/values/styles.xml

ios/YourApp/BootSplash.storyboard
ios/YourApp/Colors.xcassets/BootSplashBackground-<hash>.colorset/Contents.json
ios/YourApp/Images.xcassets/BootSplashLogo-<hash>.imageset/Contents.json
ios/YourApp/Images.xcassets/BootSplashLogo-<hash>.imageset/logo-<hash>.png
ios/YourApp/Images.xcassets/BootSplashLogo-<hash>.imageset/logo-<hash>@2x.png
ios/YourApp/Images.xcassets/BootSplashLogo-<hash>.imageset/logo-<hash>@3x.png
ios/YourApp/Info.plist
ios/YourApp.xcodeproj/project.pbxproj

harmony/entry/src/main/resources/base/media/bootsplash_logo.png
harmony/entry/src/main/resources/base/element/color.json
harmony/entry/src/main/module.json5

public/index.html

assets/bootsplash/manifest.json
assets/bootsplash/logo.png
assets/bootsplash/logo@1,5x.png
assets/bootsplash/logo@2x.png
assets/bootsplash/logo@3x.png
assets/bootsplash/logo@4x.png

编辑您的启动Ability文件,它通常是在entry模块的module.json5中abilities属性里配置的第一个ability:

+ import { window } from '@kit.ArkUI';

+ import { RNBootSplashScreen } from '@react-native-ohos/react-native-bootsplash/src/main/ets/RNBootSplashScreen';

export default class EntryAbility extends RNAbility {
+  onWindowStageCreate(windowStage: window.WindowStage) {
+     RNBootSplashScreen.init(this.context, windowStage).then(() => {
+       super.onWindowStageCreate(windowStage);
+     })
+  }

  ...
}

链接

是否支持autolink RN框架版本
~6.4.0 0.82

使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md

如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。

ManualLink: 此步骤为手动配置原生依赖项的指导

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony

1. 覆盖 RN SDK

为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。

关于该字段的作用请阅读官方说明

{
  "overrides": {
    "@rnoh/react-native-openharmony": "^0.82.7" // ohpm 在线版本
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
  }
}

2. 引入原生端代码

目前有两种方法:

  • 通过 har 包引入;
  • 直接链接源码。

方法一:通过 har 包引入(推荐)

har 包位于三方库安装路径的 `harmony` 文件夹下。

打开 entry/oh-package.json5,添加以下依赖

"dependencies": {
    "@rnoh/react-native-openharmony": "file:../react_native_openharmony",
    "@react-native-ohos/react-native-bootsplash": "file:../../node_modules/@react-native-ohos/react-native-bootsplash/harmony/boot_splash.har"
}

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

方法二:直接链接源码

如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)

3. 配置 CMakeLists 和引入 BootSplashPackage

打开 entry/src/main/cpp/CMakeLists.txt,添加:

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)

+ add_subdirectory("${OH_MODULE_DIR}/@react-native-ohos/react-native-bootsplash/src/main/cpp" ./bootsplash)

# RNOH_END: manual_package_linking_1

file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")

add_library(rnoh_app SHARED
    ${GENERATED_CPP_FILES}
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_boot_splash)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "SamplePackage.h"
+ #include "BootSplashPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
      std::make_shared<SamplePackage>(ctx),
+     std::make_shared<BootSplashPackage>(ctx)
    };
}

4. 在 ArkTs 侧引入 RNBootSplashPackage

打开 entry/src/main/ets/RNPackagesFactory.ts,添加:

  ...
+ import { RNBootSplashPackage } from '@react-native-ohos/react-native-bootsplash/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
    new SamplePackage(ctx),
+   new RNBootSplashPackage(ctx)
  ];
}

运行

点击右上角的 sync 按钮

或者在终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。

在以下版本验证通过:

  1. RNOH: 0.82.7; SDK: HarmonyOS 6.0.1 Release; IDE: DevEco Studio 6.0.1 Release; ROM:6.0.0.328 SP26;

使用示例

下面的代码展示了这个库的基本使用场景:

使用时 import 的库名不变。

示例中logo参数使用了本地图片资源,可以到[react-native-boot-splash demo](https://github.com/react-native-oh-library/RNOHDCS/tree/main/react-native-boot-splash/source)获取该图片

import { useState , useEffect} from "react";
import { Animated, View, Text, Dimensions, Platform, StatusBar, StyleSheet } from "react-native";
import BootSplash from "react-native-bootsplash";

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  text: {
    fontSize: 30,
    fontWeight: "700",
    margin: 20,
    lineHeight: 30,
    color: "#333",
    textAlign: "center",
  },
});

type Props = {
  onAnimationEnd: () => void;
};

export const AnimatedBootSplash = ({ onAnimationEnd }: Props) => {
  const [opacity] = useState(() => new Animated.Value(1));
  const [translateY] = useState(() => new Animated.Value(0));

  const { container, logo /*, brand */ } = BootSplash.useHideAnimation({
    manifest: require("../source/bootsplash_manifest.json"),
    logo: require("../source/bootsplash_logo.png"),

    animate: () => {
      const { height } = Dimensions.get("window");
      Animated.stagger(250, [
        Animated.spring(translateY, {
          useNativeDriver: true,
          toValue: -50,
        }),
        Animated.spring(translateY, {
          useNativeDriver: true,
          toValue: height,
        }),
      ]).start();
      Animated.timing(opacity, {
        useNativeDriver: true,
        toValue: 0,
        duration: 150,
        delay: 350,
      }).start(() => {
        onAnimationEnd();
      });
    },
  });

  return (
    <Animated.View {...container} style={[container.style, { opacity }]}>
      <Animated.Image
        {...logo}
        style={[logo.style, { transform: [{ translateY }] }]}
      />
    </Animated.View>
  );
};

const App = () => {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    StatusBar.setBarStyle("dark-content");
  }, []);

  return (
    <>
      <View style={styles.container}>
        <Text style={styles.text}>Hello World</Text>
        {visible && (
          <AnimatedBootSplash
            onAnimationEnd={async () => {
              await BootSplash.isVisible();
              setVisible(false);
            }}
          />
        )}
      </View>
    </>
  );
};

export default App;
// bootsplash_manifest.json
{
  "background": "#F5FCFF",
  "logo": {
    "width": 300,
    "height": 89
  }
}

接口说明

API

“Platform”列表示该属性在原三方库上支持的平台。

“HarmonyOS Support”列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

名称 描述 参数类型 必填 平台 OpenHarmony平台支持
hide 隐藏启动屏 function no Android/iOS yes
isVisible 返回原生启动屏当前的可见状态 function no Android/iOS yes
useHideAnimation 用于通过 Animated、react-native-reanimated 等方式对启动屏所有元素进行动画,从而轻松创建自定义隐藏动画的 Hook(效果类似文档顶部的视频示例) function no Android/iOS yes

hide

type hide = (config?: { fade?: boolean }) => Promise<void>;
名称 描述 参数类型 必填 平台 OpenHarmony平台支持
fade 是否以淡出效果隐藏启动屏(为 false 时立即隐藏) boolean iOS/Android partially(仅支持 fade=falsefade=true 不生效)

useHideAnimation

useHideAnimation(config: {UseHideAnimationConfig}) => {container: ContainerProps;logo: LogoProps;brand: BrandProps;};
名称 描述 参数类型 必填 平台 OpenHarmony平台支持
ready 用于延迟动画执行的就绪标志(默认值:true) boolean iOS/Android 部分支持(独立子窗口方案,与 iOS/Android 覆盖层不同,原生与 JS 协同性较弱)
manifest 在 assets 目录下由 CLI 生成的 manifest 配置文件 Manifest iOS/Android 部分支持(受限于 --dark-*/--brand 选项需付费 license 未开源,CLI 仅生成 background+logo;原生读资源不读 manifest,JS 层读 manifest 布局)
logo 动画中使用的 Logo 图片 ImageRequireSource iOS/Android 部分支持(独立子窗口方案,与 iOS/Android 覆盖层不同,原生与 JS 协同性较弱)
darkLogo 深色模式下动画中使用的 Logo 图片 ImageRequireSource iOS/Android 部分支持(受限于 --dark-* 选项需付费 license 未开源,CLI 不生成 dark logo,仅 JS 层渲染)
brand 动画中使用的品牌(Brand)图片 ImageRequireSource iOS/Android 部分支持(受限于 --brand 选项需付费 license 未开源,brand 资源无法由 CLI 生成,仅 JS 层渲染;需 manifest.brand 与 brand 同时传入)
darkBrand 深色模式下动画中使用的品牌(Brand)图片 ImageRequireSource iOS/Android 部分支持(受限于 --brand/--dark-* 选项需付费 license 未开源,CLI 不生成 darkBrand,仅 JS 层渲染;需 manifest.brand+brand)
statusBarTranslucent 设置状态栏是否为透明 boolean iOS/Android 不支持
navigationBarTranslucent 设置导航栏(虚拟按键栏)是否为透明 boolean iOS/Android 不支持
animate 自定义隐藏动画的回调函数 function iOS/Android 部分支持(独立子窗口方案,与 iOS/Android 覆盖层不同,原生与 JS 协同性较弱)

遗留问题

其他

  • 执行generate-bootsplash命令行时,由于 --brand, --brand-width 和 --dark-* 选项需要购买license才能使用,涉及功能未开源,HarmonyOS平台不支持使用

目录结构

/rntpc_react-native-bootsplash  # 项目根目录
├── harmony              # 鸿蒙适配代码
│    └─ boot_splash.har          # har包
│    └─ boot_splash              # 鸿蒙适配核心代码
│          └─ index.ets    # 鸿蒙适配代码入口    
│          └─ src/main/ets  
│              └─ RNBootSplashScreen  # 启动屏核心实现   
├── src                  # RN代码
│    └─ index.ts  # 入口文件 
│    └─ NativeRNBootSplash.ts # 类型文件
│    └─ generate.ts # 工具函数文件          
├── README_en.md           # 英文文档
├── README.md   # 中文文档

贡献代码

使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR

开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。

项目介绍

基于 react-native-bootsplash 的 OpenHarmony 适配版,启动屏(Boot Splash)显示与隐藏控制

定制我的领域