首页 / 文章

为iOS和Android上的React Native应用添加启动画面。

iOS和Android上的React Native启动画面:Xcode的启动界面、Android的主题与布局,以及用于消除白色闪光的react-native-splash-screen组件。

发布者:REACTAPP.TOP阅读约 6 分钟1406 词

来源: How to Add a Splash Screen to a React Native App (iOS and Android)

要将 React Native 应用发布到应用商店,仅仅开发应用本身是不够的。在提交审核之前,还需要准备图标、描述以及启动画面,而启动画面的制作则涉及原生代码的运用。以下步骤介绍了在 iOS 和 Android 平台的对应 IDE 中使用少量原生代码来完成这些工作的方法。这些说明基于 react-native-splash-screen 3.0.6 版本以及 react-native link 工具,因此较新版本的 React Native 可能会有不同的处理方式。

使用 Expo 或 Create React Native App 创建的项目无需处理这些内容,因为它们的官方文档仅用几行文字就介绍了启动画面的相关设置。

创建一个新项目是个不错的起点,例如可以执行 react-native init SplashExample 命令。在修改任何内容之前,先将其纳入版本控制之下。这样既能方便地撤销错误,也能清楚地看出启动画面涉及哪些文件。

设计资源文件

早期的做法是使用一张大的图片作为启动画面,但在屏幕分辨率日益多样化的情况下,这种方式的显示效果很差。一个更好的方案是从类似应用图标的简单正方形图片开始,原因有二。

  1. 这样能给人一种点击后的图标会逐渐放大并填满屏幕的印象,从而使过渡过程显得更加流畅。
  2. 设计更为简单。启动画面只需显示几毫秒,因此无需承载过多信息,毕竟它只是个加载界面而已。

请将此正方形图片导出为三种尺寸:200像素用于@1x分辨率,400像素用于@2x分辨率,600像素用于@3x分辨率。

能让闪光效果更明显的背景

如果您之前在 React Native 中使用过启动画面,可能会发现内容出现前会有白色闪光。在背景为白色的应用中很难察觉,但仍然很烦人。为确保这种闪光不会被忽视,请为演示应用设置深色背景:在 App.js 中将背景颜色设置为 #4F6D7A,文本颜色设置为 #F5FCFF,并将状态栏的文字改为浅色。

iOS

在 Xcode 中打开该项目:

open ios/SplashExample.xcodeproj

首先添加一个图片资源。在左侧导航器中,进入 SplashExample,再进入 SplashExample,接着选择 Images.xcassets,然后在第二个导航列中的加号按钮上点击。将该资源的名称设为 SplashIcon。将三张图片放入其中,Xcode会自动为每张图片分配合适的像素密度。

接下来从左侧导航器中打开 LaunchScreen.xib。该文件包含两个文本元素,分别是项目名称和“Powered by React Native”。选中这两个元素并将其删除。

设置视图的背景。在第二个导航器中选择 View,然后在右侧面板中选择 Background 以打开颜色选择器。有一个需要花些时间才能发现的技巧:在颜色选择器中选择第二个标签页,再选择“RGB Sliders”,就会出现一个可以输入十六进制值的字段,输入 #4F6D7A 即可。

现在添加一个图像视图。打开对象库(工具面板右下角的第三个图标),搜索“image”,然后将图像视图拖放到彩色视图上。在右上角的属性面板中,选择SplashIcon作为图片。将该面板中从上数第二项的内容模式设置为“保持比例”,这样图片的比例就能保持正确。

为了让图标在任何设备上都居中,打开标尺选项卡(右侧面板顶部的第五个图标)。在“自动调整大小”框中,关闭外侧的红色线条,开启内侧的红色箭头。这样无论屏幕尺寸如何,图片都会保持居中。

这样虽然做出了启动画面,但仍然存在白色闪光。

闪光现象产生的原因

应用启动时,iOS会立即显示启动界面。随后React Native需要时间来初始化:JavaScript正在加载,桥接组件也在启动。在这段时间内,原生启动界面会消失,且尚未有任何内容渲染出来,因此你会看到空白画面。解决方法是让启动画面比默认时间显示得更久一些,直到JavaScript准备就绪。react-native-splash-screen包就能实现这一点。

安装该包并将其关联到项目中:

yarn add react-native-splash-screen@3.0.6
react-native link react-native-splash-screen

接着配置原生端。在 Xcode 中打开 AppDelegate.m,在其他导入语句之后加入该包的头文件导入 SplashScreen.h,然后在 didFinishLaunchingWithOptions 方法内的 return YES; 之前直接调用 [SplashScreen show];。

在 JavaScript 端,需在应用准备就绪时让启动画面消失。在 App.js 的 componentDidMount 方法中调用该包的隐藏方法。

目前效果不错,仅剩一个小问题:启动画面显示时的状态栏颜色。在 Info.plist 中添加一行,键值为 UIStatusBarStyle,字符串值为 UIStatusBarStyleLightContent。这样 iOS 端的配置就完成了。

Android

Android 的实现稍复杂一些,因为需要两个独立的启动画面。一个来自 react-native-splash-screen,另一个则在应用加载视图之前显示。

资源文件

将图片复制到 android/app/src/main/res 下的 mipmap 文件夹中。Android 对不同密度级别的文件命名方式与 iOS 不同,因此需要对这些文件进行对应映射:

  • mipmap-mdpi 对应 1x 分辨率的图片。
  • mipmap-hdpi 对应 2x 分辨率的图片。
  • mipmap-xhdpi 对应 3x 分辨率的图片。
  • mipmap-xxhdpi 也对应 3x 分辨率的图片。

在每个文件夹中,将文件重命名为 icon.png。

应用冷启动时的启动画面

当应用从初始状态启动时,会显示第一个界面。该实现方法参考了Big Nerd Ranch上一篇关于如何正确制作启动界面的知名文章,文中对相关原理进行了更深入的阐述。

  1. 在android/app/src/main/res/drawable目录下创建background_splash.xml文件。可能还需要先创建drawable目录。该文件定义了一个layer-list,即多层堆叠结构。第一层填充背景颜色(稍后会定义),第二层则显示图标,图标尺寸为200dp×200dp,且居中显示。
  2. 在android/app/src/main/res/values目录下创建colors.xml文件,并定义应用所使用的蓝色颜色值。
  • 在同一个文件夹中的styles.xml文件里定义一个SplashTheme。该主题以background_splash作为窗口背景,状态栏颜色设为蓝色,从而尽可能真实地模拟原生应用,包括状态栏的变化。同时要确保默认主题的状态栏颜色设置正确。
  • 在AndroidManifest.xml中,让应用首先使用SplashTheme。在<application>标签内,注册一个新的SplashActivity作为启动活动,并调整MainActivity使其不再作为启动入口。注意在较新版本的Android系统中,需要在必要位置设置android:exported="true"。
  • 创建SplashActivity.java文件。它的唯一功能就是立即跳转至真正的React Native应用MainActivity。
  • 运行该应用,然后退出使其下次启动时为冷启动状态,再重新打开它。启动画面会立即出现,随后是同样的白色闪光。修复这个问题所需的工作量比在iOS上稍多一些,但并非很多。

    在JavaScript准备就绪前保持启动画面显示

    如果相关包尚未安装,请添加该包并建立链接:

    yarn add react-native-splash-screen@3.0.6
    react-native link
    

    在 MainActivity.java 中添加该包的初始化调用,即可配置原生 Android 端。在 App.js 中,需确保应用加载后立即关闭启动画面,与 iOS 的处理方式一致。

    接着在 android/app/src/main/res/layout 中创建 launch_screen.xml 文件。文件名很重要,因为库会依据它来查找。请使用 LinearLayout 作为根元素。Android Studio 提供了类似 Xcode Interface Builder 的可视化编辑器,但直接编辑 XML 更为简便。将布局的居中方式设置为居中,背景色设为蓝色,其余参数保持默认值。在布局内部添加一个用于显示图标的 ImageView。

    ImageView 的属性如下:

    • android:layout_width 和 android:layout_height 用于设置尺寸,需与 background_splash.xml 中的尺寸一致。
  • android:layout_marginTop 的值应等于状态栏的高度。如果不设置该属性,图标的位置会与第一个启动画面中的位置略有不同,因此在切换画面时会出现明显的位移。
  • android:src="@mipmap/icon" 用于指定图片的路径。
  • 最后,colors.xml 还需要添加一条记录:

    <color name="primary_dark">#4F6D7A</color>
    

    如果跳过这一步,应用在启动时会崩溃。原因是 react-native-splash-screen 本身存在缺陷,后续版本可能会取消这一功能。

    当这两部分都配置妥当后,应用在 iOS 和 Android 上启动时都会显示无闪烁的连续启动画面。

    相关阅读

  • 当 React 记忆化适得其反:为何更少的渲染反而让应用变慢 — 讲述了 memo、useMemo 和 useCallback 如何在大型 React 页面中增加成本并引发错误,以及为何将状态移出这些函数并分析整个交互流程才能解决问题。