首发于公众号 前端混合开发,欢迎关注。
在这个教程中,我们将演示如何在React Native中构建一个启动屏幕。我们将指导你如何使用 react-native-splash-screen 为iOS和Android应用构建出色的欢迎界面。此外,由于Expo很受欢迎,许多人常常选择使用它,我们也将探讨如何在Expo中构建启动屏幕。
什么是启动画面?
启动画面是用户访问应用程序其余功能之前出现的第一个屏幕。可以说,启动画面是让您的移动应用的品牌名称和图标深入用户记忆的最佳方式。
在网络应用中,我们使用预加载器为用户提供动画娱乐,同时服务器操作正在处理中。尽管这听起来很直接,但它是构建和保留用户群的关键工具。
在React Native中创建启动屏有很多好处。例如,考虑一个从API加载数据的场景。在用户等待时显示加载器是一种良好的用户体验。同样的情况也适用于启动屏,因为在应用程序启动时立即显示加载器可以帮助你在用户等待应用程序准备就绪时,向他们展示一个有组织的,设计良好的显示界面。
对于这个 react-native-splash-screen
演示,我们将为Android 和 iOS 构建一个启动屏幕。本教程将指导你如何准备合适的图片大小,更新必要的文件,并在应用加载时隐藏启动屏幕。完成后的应用将如下图所示
为什么启动画面的图片大小很重要
为移动应用创建启动画面可能会有些棘手,你肯定不希望由于启动画面分辨率的不一致在某些设备上出现显示问题。例如,安卓设备的需求与iOS完全不同。大多数有经验的设计师可以从零开始为两种设备创建所需的启动画面分辨率。
然而,有许多可用的第三方工具可以帮助你为Android和iOS创建启动屏幕。在这个教程中,我们将使用 App Icon Generator,这是一个用于创建Android和iOS应用图标和图片的在线平台。
在你继续之前,请确保你有一张高清的,2000x2000像素(72 PPI)的图片准备好。你可以在GitHub上克隆这些教程的完整源代码。
构建一个React Native启动屏幕
首先,前往Appicon。将你的图片拖到提供的框中,然后选择4x
作为你的基础尺寸。勾选 iOS 和 Android,然后点击生成:
接下来,解压下载的文件,并将 iOS 和 Android 文件夹复制到你克隆的启动项目的 assets
目录中的 assets
文件夹里:
在React Native 中构建启动屏需要一些微调。首先,使用下面的任一命令安装 react-native-splash-screen
包:
/* npm */
npm i react-native-splash-screen --save
/* yarn */
yarn add react-native-splash-screen
为iOS构建一个启动屏幕
在你的终端中,使用下面的命令链接依赖项:
cd ios // to enter into IOS directory
pod install
接下来,导航到 AppDelegate.m
文件并用以下代码进行更新。添加代码 #import "RNSplashScreen"
(第6行),并将默认设置为显示启动屏 [RNSplashScreen show
] (第41行)。请参考下面代码中的注释:
/* ios/SplashScreen/AppDelegate.m */
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
// Import RNSplashScreen
#import "RNSplashScreen.h"
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"MySplashScreen"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// Set the splash screen to show by default.
[RNSplashScreen show];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end
在上述代码中,我们对 AppDeligate 文件做了两个重要的修改。首先,我们将之前安装的 RNSplashScreen
导入到 AppDeligate.m
中。接下来,我们用代码 [RNSplashScreen show]
设置 RNSplashScreen
默认显示。
接下来,在 Xcode 中打开项目工作区,点击 Images,右键点击 Appicon 下方的任意位置,选择 New Image Set
。将图片名称设置为“splash”,打开 assets 文件夹,导航到 iOS 文件夹。将 iOS 中的三张图片拖到 Xcode 上命名为 1x, 2x 和 3x 的三个框中:
接下来,选择 LaunchScreen.storyboard
。选择 View Controller Scene > View Controller > View
,点击 SplashScreen
和 Powered by React Native
标签,并在键盘上按 Delete 键。
接下来,选择 View
并点击 Xcode 右上角的尺子图标。取消选中 Safe Area Layout Guide
选项,点击加号图标 +,在对象搜索输入框中输入“image view
”,然后将“image view”拖到 View 画布上:
现在我们已经设置好了图像视图,点击图像属性图标并将图像更改为“splash
”。将内容模式设置为“aspect fit
”,如下所示:
更改iOS启动屏幕颜色
你可能会问的下一个问题是“我如何在 React Native 中更改启动屏幕的背景颜色?”为了在 iOS 中为启动屏幕强制使用一致的背景,滚动到背景设置位置并从下拉菜单中选择 Custom。在弹出窗口中,选择启动屏幕的期望颜色。在我们的例子中,我们选择了白色:
为了确认你的应用可以成功运行,请从Xcode运行一个构建。你应该会看到类似这样的情况:
为Android构建启动屏幕
对于Android,导航到 MainActivity.java
文件并更新代码以使用下面的 react-native-splash-screen 代码:
/* android/app/src/main/java/MainActivity.java */
package com.mysplashscreen;
import android.os.Bundle; // Add this here
import com.facebook.react.ReactActivity;
import org.devio.rn.splashscreen.SplashScreen; // Add this here
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "MySplashScreen";
}
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this); // Add this here
super.onCreate(savedInstanceState);
}
}
接下来,在 app/src/main/res/layout
中创建一个名为 launch_screen.xml
的文件。另外,如果 layout
文件夹不存在,也要创建它:
/* launch_screen.xml */
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/launch_screen" android:scaleType="centerCrop" />
</RelativeLayout>
注意, <ImageView android:src="@drawable/launch_screen" /> 在HTML中等同于 <img src="your_image" />
,所以请确保用你的自定义图片的实际名称替换 launch_screen
。
然而,Android会自动缩放可绘制的图像,所以你不一定需要为不同的手机尺寸提供图片。回想一下,我们之前将两个文件夹(Android和iOS)复制到了我们的资产目录。这两个文件夹包含了我们为不同手机密度提供的启动画面图片。
将 Android 目录中的 drawable folders/assets
复制到可以在 android/app/src/main/res/
中找到的 res
目录中。
更改Android的启动屏幕颜色
要更改Android应用的启动屏幕背景颜色,请在values文件夹中创建一个名为 colors.xml
的文件,并复制下面的代码:
/* app/src/main/res/values/colors.xml */
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary_dark">#000000</color>
</resources>
在上述代码中,我们正在创建一个主色,这将是我们首选的背景色。然后,打开Android Studio中的Android文件夹,打开AVD,并按照下面的方式运行你的应用程序。如果一切设置正确,你应该会看到类似于这样的结果:
在应用加载后隐藏启动屏幕
为了在应用加载时隐藏启动屏幕,我们将使用之前安装的 react-native-splash-screen
包。在你的 App.js
文件中,复制下面的代码:
/* App.js */
import React, {useEffect} from 'react';
import {
StatusBar,
StyleSheet,
SafeAreaView,
useColorScheme,
} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import SplashScreen from 'react-native-splash-screen';
import Login from './src/Login';
function App() {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
useEffect(() => {
SplashScreen.hide();
}, []);
return (
<SafeAreaView style={[styles.container, backgroundStyle]}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<Login />
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default App;
在我们的 Login.js
文件中:
/* Login.js */
import React, {useState} from 'react';
import {
StyleSheet,
View,
Image,
Text,
TextInput,
TouchableOpacity,
} from 'react-native';
import logo from '../assets/skout_logo.png';
export default function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<View style={styles.container}>
<View style={styles.logoView}>
<Image source={logo} resizeMode="contain" style={styles.logo} />
</View>
<View style={styles.inputView}>
<TextInput
value={email}
style={styles.inputText}
placeholder="+2340899004909"
placeholderTextColor="#AFAFAF"
onChangeText={email => setEmail(email)}
/>
</View>
<View style={styles.inputView}>
<TextInput
value={password}
style={styles.inputText}
placeholder="Password"
placeholderTextColor="#AFAFAF"
onChangeText={password => setPassword(password)}
/>
</View>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<View style={styles.actions}>
<TouchableOpacity style={{marginHorizontal: 15}}>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.singUp}>Signup</Text>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
logo: {
fontWeight: 'bold',
fontSize: 50,
color: '#fb5b5a',
marginBottom: 40,
},
inputView: {
width: '80%',
backgroundColor: '#EAEAEA',
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: 'center',
padding: 20,
},
inputText: {
height: 50,
color: '#777777',
fontWeight: '800',
},
singUp: {
color: '#39B54A',
fontWeight: '500',
},
loginBtn: {
width: '80%',
backgroundColor: '#39B54A',
borderRadius: 25,
height: 50,
alignItems: 'center',
justifyContent: 'center',
marginTop: 20,
marginBottom: 10,
},
loginText: {
color: '#ffffff',
fontWeight: '800',
},
actions: {
flexDirection: 'row',
alignItems: 'flex-start',
justifyContent: 'flex-start',
},
logoView: {
flexDirection: 'row',
alignItems: 'flex-start',
marginBottom: 15,
marginTop: 0,
},
logo: {
marginBottom: 25,
width: 250,
height: 100,
},
});
应用加载后,程序将显示登录页面。请参考下面的截图:
构建一个Expo启动屏幕
到目前为止,我们已经探讨了如何在一个裸 React Native 应用中构建启动屏幕。使用 Expo,我们可以以简化和直接的方式做到这一点,因为 Expo 允许我们在 app.json
文件中配置我们的启动屏幕和图片。
我们将使用上述的 App.js
和 Login.js
文件。这就是我们搭建新项目时 app.json
文件的样子:
/* app.json */
{
"expo": {
"name": "splash-screen",
"slug": "splash-screen",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
如果你观察上面代码中的 splash
值(对象),你会看到我们的启动图像指向我们的 assets
文件夹,那里有默认的启动图像。我们可以用我们的自定义图像替换它。同样,我们可以调整图像的大小(即 contain
、cover
、stretch
),以更好地适应我们的屏幕,最后,我们可以根据我们的选择设置背景颜色。
对于我们的示例,我已经将图片替换为我们的自定义图片,然后将背景更改为我们的样式:
/* app.json */
{
"expo": {
....
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#39B54A"
},
....
}
如你所见,只要我们的应用加载或准备就绪,启动屏幕就会立即隐藏。为了优化用户体验,我们可以选择在隐藏之前显示启动屏幕几秒钟。为了做到这一点,我们将使用 expo-splash-screen
包,我们可以用以下命令来安装:
npx expo install expo-splash-screen
接下来,在我们的 App.js
文件中,我们导入并调用它:
/* App.js */
import * as SplashScreen from 'expo-splash-screen';
SplashScreen.preventAutoHideAsync();
setTimeout(SplashScreen.hideAsync, 5000);
通过这个,我们将看到我们的启动屏幕持续五秒钟后才隐藏。这就是结果:
总结
启动画面是对任何应用程序的重要补充,因为它在启动应用程序和显示主要内容之间创造了平滑的过渡,从而提高了用户的体验。启动画面有助于强化应用程序的身份,使其容易被用户识别,从而提高品牌建设。
通常,某些配置和资源(如字体和检查更新)会在应用准备就绪时立即实施。启动屏幕有助于在这些资源加载期间让用户忙碌,而不是延迟会损害用户体验的情况。
交流
首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。