1 | # 🚀 react-native-bootsplash
|
2 |
|
3 | [![npm version](https://badge.fury.io/js/react-native-bootsplash.svg)](https://badge.fury.io/js/react-native-bootsplash) [![npm](https://img.shields.io/npm/dt/react-native-bootsplash.svg)](https://www.npmjs.org/package/react-native-bootsplash) ![Platform - Android and iOS](https://img.shields.io/badge/platform-Android%20%7C%20iOS-yellow.svg) ![MIT](https://img.shields.io/dub/l/vibe-d.svg) [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
|
4 |
|
5 | Show a bootsplash during app startup. Hide it when you are ready.
|
6 |
|
7 | <p>
|
8 | <img height="520" src="https://raw.githubusercontent.com/zoontek/react-native-bootsplash/HEAD/docs/ios_demo.gif?raw=true" alt="iOS demo"></img>
|
9 | <img width="300" src="https://raw.githubusercontent.com/zoontek/react-native-bootsplash/HEAD/docs/android_demo.gif?raw=true" alt="android demo"></img>
|
10 | </p>
|
11 |
|
12 | ## Support
|
13 |
|
14 | | version | react-native version |
|
15 | | ------- | -------------------- |
|
16 | | 3.0.0+ | 0.63.0+ |
|
17 | | 2.0.0+ | 0.60.0+ |
|
18 |
|
19 | For 0.59-, you should use [`jetify -r`](https://github.com/mikehardy/jetifier/blob/master/README.md#to-reverse-jetify--convert-node_modules-dependencies-to-support-libraries)
|
20 |
|
21 | ## Installation
|
22 |
|
23 | ```bash
|
24 | $ npm install --save react-native-bootsplash
|
25 | # --- or ---
|
26 | $ yarn add react-native-bootsplash
|
27 | ```
|
28 |
|
29 | Don't forget going into the `ios` directory to execute a `pod install`.
|
30 |
|
31 | ## 🆘 Manual linking
|
32 |
|
33 | Because this package targets React Native 0.60.0+, you will probably don't need to link it manually. Otherwise if it's not the case, follow this additional instructions:
|
34 |
|
35 | <details>
|
36 | <summary><b>👀 See manual linking instructions</b></summary>
|
37 |
|
38 | ### iOS
|
39 |
|
40 | Add this line to your `ios/Podfile` file, then run `pod install`.
|
41 |
|
42 | ```bash
|
43 | target 'YourAwesomeProject' do
|
44 | # …
|
45 | pod 'RNBootSplash', :path => '../node_modules/react-native-bootsplash'
|
46 | end
|
47 | ```
|
48 |
|
49 | ### Android
|
50 |
|
51 | 1. Add the following lines to `android/settings.gradle`:
|
52 |
|
53 | ```gradle
|
54 | include ':react-native-bootsplash'
|
55 | project(':react-native-bootsplash').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-bootsplash/android')
|
56 | ```
|
57 |
|
58 | 2. Add the implementation line to the dependencies in `android/app/build.gradle`:
|
59 |
|
60 | ```gradle
|
61 | dependencies {
|
62 | // ...
|
63 | implementation project(':react-native-bootsplash')
|
64 | }
|
65 | ```
|
66 |
|
67 | 3. Add the import and link the package in `MainApplication.java`:
|
68 |
|
69 | ```java
|
70 | import com.zoontek.rnbootsplash.RNBootSplashPackage; // <- add the RNBootSplashPackage import
|
71 |
|
72 | public class MainApplication extends Application implements ReactApplication {
|
73 |
|
74 | // …
|
75 |
|
76 | @Override
|
77 | protected List<ReactPackage> getPackages() {
|
78 | @SuppressWarnings("UnnecessaryLocalVariable")
|
79 | List<ReactPackage> packages = new PackageList(this).getPackages();
|
80 | // …
|
81 | packages.add(new RNBootSplashPackage());
|
82 | return packages;
|
83 | }
|
84 |
|
85 | // …
|
86 | }
|
87 | ```
|
88 |
|
89 | </details>
|
90 |
|
91 | ## Setup
|
92 |
|
93 | ### Assets generation
|
94 |
|
95 | In order to speed up the setup, we provide a **CLI** to generate assets, create the Android Drawable XML file and the iOS Storyboard file automatically ✨.
|
96 |
|
97 | ```bash
|
98 | $ npx react-native generate-bootsplash --help
|
99 | # --- or ---
|
100 | $ yarn react-native generate-bootsplash --help
|
101 | ```
|
102 |
|
103 | The command can take multiple arguments:
|
104 |
|
105 | ```bash
|
106 | react-native generate-bootsplash <logoPath>
|
107 |
|
108 | Generate a launch screen using an original logo file
|
109 |
|
110 | Options:
|
111 | --background-color <color> color used as launch screen background (in hexadecimal format) (default: "#fff")
|
112 | --logo-width <width> logo width at @1x (in dp - we recommand approximately ~100) (default: 100)
|
113 | --assets-path [path] path to your static assets directory (useful to require the logo file in JS)
|
114 | -h, --help output usage information
|
115 | ```
|
116 |
|
117 | #### Full command usage example
|
118 |
|
119 | ```bash
|
120 | yarn react-native generate-bootsplash assets/bootsplash_logo_original.png \
|
121 | --background-color=F5FCFF \
|
122 | --logo-width=100 \
|
123 | --assets-path=assets
|
124 | ```
|
125 |
|
126 | ![](https://raw.githubusercontent.com/zoontek/react-native-bootsplash/master/docs/cli_tool.png?raw=true)
|
127 |
|
128 | This tool relies on the naming conventions that are used in the `/example` project and will therefore create the following files:
|
129 |
|
130 | ```bash
|
131 | android/app/src/main/res/drawable/bootsplash.xml
|
132 | android/app/src/main/res/values/colors.xml (creation and edition)
|
133 | android/app/src/main/res/mipmap-hdpi/bootsplash_logo.png
|
134 | android/app/src/main/res/mipmap-mdpi/bootsplash_logo.png
|
135 | android/app/src/main/res/mipmap-xhdpi/bootsplash_logo.png
|
136 | android/app/src/main/res/mipmap-xxhdpi/bootsplash_logo.png
|
137 | android/app/src/main/res/mipmap-xxxhdpi/bootsplash_logo.png
|
138 |
|
139 | ios/YourProjectName/BootSplash.storyboard
|
140 | ios/YourProjectName/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png
|
141 | ios/YourProjectName/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png
|
142 | ios/YourProjectName/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png
|
143 |
|
144 | # Only if --assets-path was specified
|
145 | assets/bootsplash_logo.png
|
146 | assets/bootsplash_logo@1,5x.png
|
147 | assets/bootsplash_logo@2x.png
|
148 | assets/bootsplash_logo@3x.png
|
149 | assets/bootsplash_logo@4x.png
|
150 | ```
|
151 |
|
152 | ### iOS
|
153 |
|
154 | _⚠️ Only `.storyboard` files are supported ([Apple will deprecate other methods in April 2020](https://developer.apple.com/news/?id=01132020b))._
|
155 |
|
156 | Edit the `ios/YourProjectName/AppDelegate.m` file:
|
157 |
|
158 | ```obj-c
|
159 | #import "AppDelegate.h"
|
160 |
|
161 | #import <React/RCTBridge.h>
|
162 | #import <React/RCTBundleURLProvider.h>
|
163 | #import <React/RCTRootView.h>
|
164 |
|
165 | #import "RNBootSplash.h" // <- add the header import
|
166 |
|
167 | @implementation AppDelegate
|
168 |
|
169 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
170 | {
|
171 | // …
|
172 | rootViewController.view = rootView;
|
173 | self.window.rootViewController = rootViewController;
|
174 | [self.window makeKeyAndVisible];
|
175 |
|
176 | [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView]; // <- initialization using the storyboard file name
|
177 |
|
178 | return YES;
|
179 | }
|
180 | ```
|
181 |
|
182 | Set the `BootSplash.storyboard` as launch screen file:
|
183 |
|
184 | | Drag and drop the file | Create folder reference | Set as Launch Screen File |
|
185 | | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
186 | | ![](https://raw.githubusercontent.com/zoontek/react-native-bootsplash/master/docs/xcode-1.png?raw=true) | ![](https://raw.githubusercontent.com/zoontek/react-native-bootsplash/master/docs/xcode-2.png?raw=true) | ![](https://raw.githubusercontent.com/zoontek/react-native-bootsplash/master/docs/xcode-3.png?raw=true) |
|
187 |
|
188 | ### Android
|
189 |
|
190 | 1. Edit the `android/app/src/main/java/com/yourprojectname/MainActivity.java` file:
|
191 |
|
192 | ```java
|
193 | import android.os.Bundle; // <- add this necessary import
|
194 |
|
195 | import com.facebook.react.ReactActivity;
|
196 | import com.zoontek.rnbootsplash.RNBootSplash; // <- add this necessary import
|
197 |
|
198 | public class MainActivity extends ReactActivity {
|
199 |
|
200 | // …
|
201 |
|
202 | @Override
|
203 | protected void onCreate(Bundle savedInstanceState) {
|
204 | super.onCreate(savedInstanceState);
|
205 | RNBootSplash.init(R.drawable.bootsplash, MainActivity.this); // <- display the generated bootsplash.xml drawable over our MainActivity
|
206 | }
|
207 | ```
|
208 |
|
209 | As Android will not create our main activity before launching the app, we need to display a different activity at start, then switch to our main one.
|
210 |
|
211 | 2. Edit the `android/app/src/main/res/values/styles.xml` file:
|
212 |
|
213 | ```xml
|
214 | <resources>
|
215 |
|
216 | <!-- Base application theme -->
|
217 | <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
218 | <!-- Your base theme customization -->
|
219 | </style>
|
220 |
|
221 | <!-- Add the following lines (BootTheme should inherit from AppTheme) -->
|
222 | <style name="BootTheme" parent="AppTheme">
|
223 | <!-- set the generated bootsplash.xml drawable as activity background -->
|
224 | <item name="android:background">@drawable/bootsplash</item>
|
225 | </style>
|
226 |
|
227 | </resources>
|
228 | ```
|
229 |
|
230 | 3. Edit the `android/app/src/main/AndroidManifest.xml` file:
|
231 |
|
232 | ```xml
|
233 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
234 | package="com.rnbootsplashexample">
|
235 |
|
236 | <!-- … -->
|
237 |
|
238 | <application
|
239 | android:name=".MainApplication"
|
240 | android:label="@string/app_name"
|
241 | android:icon="@mipmap/ic_launcher"
|
242 | android:roundIcon="@mipmap/ic_launcher_round"
|
243 | android:allowBackup="false"
|
244 | android:theme="@style/AppTheme">
|
245 |
|
246 | <activity
|
247 | android:name=".MainActivity"
|
248 | android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
249 | android:label="@string/app_name"
|
250 | android:windowSoftInputMode="adjustResize"
|
251 | android:exported="true"
|
252 | android:launchMode="singleTask">
|
253 | <!-- ⚠️ add android:exported="true" and android:launchMode="singleTask" above -->
|
254 | <!-- remove the <intent-filter> from .MainActivity -->
|
255 | </activity>
|
256 |
|
257 | <!-- add the following lines (use the theme you created at step 2) -->
|
258 | <activity
|
259 | android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
|
260 | android:theme="@style/BootTheme"
|
261 | android:launchMode="singleTask">
|
262 | <intent-filter>
|
263 | <action android:name="android.intent.action.MAIN" />
|
264 | <category android:name="android.intent.category.LAUNCHER" />
|
265 | </intent-filter>
|
266 | </activity>
|
267 |
|
268 | <!-- … -->
|
269 |
|
270 | </application>
|
271 |
|
272 | </manifest>
|
273 | ```
|
274 |
|
275 | ## API
|
276 |
|
277 | ### hide()
|
278 |
|
279 | #### Method type
|
280 |
|
281 | ```ts
|
282 | type hide = (config?: { fade?: boolean }) => Promise<void>;
|
283 | ```
|
284 |
|
285 | #### Usage
|
286 |
|
287 | ```js
|
288 | import RNBootSplash from "react-native-bootsplash";
|
289 |
|
290 | RNBootSplash.hide(); // immediate
|
291 | RNBootSplash.hide({ fade: true }); // fade
|
292 | ```
|
293 |
|
294 | ---
|
295 |
|
296 | ### show()
|
297 |
|
298 | #### Method type
|
299 |
|
300 | ```ts
|
301 | type show = (config?: { fade?: boolean }) => Promise<void>;
|
302 | ```
|
303 |
|
304 | #### Usage
|
305 |
|
306 | ```js
|
307 | import RNBootSplash from "react-native-bootsplash";
|
308 |
|
309 | RNBootSplash.show(); // immediate
|
310 | RNBootSplash.show({ fade: true }); // fade
|
311 | ```
|
312 |
|
313 | ---
|
314 |
|
315 | ### getVisibilityStatus()
|
316 |
|
317 | #### Method type
|
318 |
|
319 | ```ts
|
320 | type VisibilityStatus = "visible" | "hidden" | "transitioning";
|
321 | type getVisibilityStatus = () => Promise<VisibilityStatus>;
|
322 | ```
|
323 |
|
324 | #### Usage
|
325 |
|
326 | ```js
|
327 | import RNBootSplash from "react-native-bootsplash";
|
328 |
|
329 | RNBootSplash.getVisibilityStatus().then((status) => console.log(status));
|
330 | ```
|
331 |
|
332 | ## Real world example
|
333 |
|
334 | ```js
|
335 | import React, { useEffect } from "react";
|
336 | import { Text } from "react-native";
|
337 | import RNBootSplash from "react-native-bootsplash";
|
338 |
|
339 | function App() {
|
340 | useEffect(() => {
|
341 | const init = async () => {
|
342 | // …do multiple sync or async tasks
|
343 | };
|
344 |
|
345 | init().finally(async () => {
|
346 | await RNBootSplash.hide({ fade: true });
|
347 | console.log("Bootsplash has been hidden successfully");
|
348 | });
|
349 | }, []);
|
350 |
|
351 | return <Text>My awesome app</Text>;
|
352 | }
|
353 | ```
|
354 |
|
355 | **🤙 A more complex example is available in the [`/example` folder](example).**
|
356 |
|
357 | ## Guides
|
358 |
|
359 | ### Handle deep linking (on Android)
|
360 |
|
361 | If you want to correctly handle [deep linking](https://developer.android.com/training/app-links/deep-linking) with this package, you should edit the `android/app/src/main/AndroidManifest.xml` file like this:
|
362 |
|
363 | ```xml
|
364 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
365 | package="com.rnbootsplashexample">
|
366 |
|
367 | <!-- … -->
|
368 |
|
369 | <application
|
370 | android:name=".MainApplication"
|
371 | android:label="@string/app_name"
|
372 | android:icon="@mipmap/ic_launcher"
|
373 | android:roundIcon="@mipmap/ic_launcher_round"
|
374 | android:allowBackup="false"
|
375 | android:theme="@style/AppTheme">
|
376 |
|
377 | <activity
|
378 | android:name=".MainActivity"
|
379 | android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
380 | android:label="@string/app_name"
|
381 | android:windowSoftInputMode="adjustResize"
|
382 | android:exported="true"
|
383 | android:launchMode="singleTask">
|
384 | <!-- ⚠️ add android:exported="true" and android:launchMode="singleTask" above -->
|
385 | <!-- remove the <intent-filter> from .MainActivity -->
|
386 | </activity>
|
387 |
|
388 | <activity
|
389 | android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
|
390 | android:theme="@style/BootTheme"
|
391 | android:launchMode="singleTask">
|
392 | <intent-filter>
|
393 | <action android:name="android.intent.action.MAIN" />
|
394 | <category android:name="android.intent.category.LAUNCHER" />
|
395 | </intent-filter>
|
396 |
|
397 | <!-- add your deep linking instructions inside the RNBootSplashActivity declaration -->
|
398 | <intent-filter>
|
399 | <action android:name="android.intent.action.VIEW" />
|
400 | <category android:name="android.intent.category.DEFAULT" />
|
401 | <category android:name="android.intent.category.BROWSABLE" />
|
402 | <data android:scheme="YOUR APP SCHEME" /> <!-- replace this with your custom scheme -->
|
403 | </intent-filter>
|
404 | </activity>
|
405 |
|
406 | <!-- … -->
|
407 |
|
408 | </application>
|
409 |
|
410 | </manifest>
|
411 | ```
|
412 |
|
413 | ### Testing with Jest
|
414 |
|
415 | Testing code which uses this library required some setup since we need to mock the native methods.
|
416 |
|
417 | To add the mocks, create a file _jest/setup.js_ (or any other file name) containing the following code:
|
418 |
|
419 | ```js
|
420 | jest.mock("react-native-bootsplash", () => {
|
421 | return {
|
422 | hide: jest.fn().mockResolvedValueOnce(),
|
423 | show: jest.fn().mockResolvedValueOnce(),
|
424 | getVisibilityStatus: jest.fn().mockResolvedValue("hidden"),
|
425 | };
|
426 | });
|
427 | ```
|
428 |
|
429 | After that, we need to add the setup file in the jest config. You can add it under [setupFiles](https://jestjs.io/docs/en/configuration.html#setupfiles-array) option in your jest config file:
|
430 |
|
431 | ```json
|
432 | {
|
433 | "setupFiles": ["<rootDir>/jest/setup.js"]
|
434 | }
|
435 | ```
|
436 |
|
437 | ## 🕵️♂️ Comparison with [react-native-splash-screen](https://github.com/crazycodeboy/react-native-splash-screen)
|
438 |
|
439 | - If `react-native-splash-screen` encourages you to display an image over your application, `react-native-bootsplash` way-to-go is to design your launch screen using platforms tools ([Xcode layout editor](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/) and [Android drawable resource](https://developer.android.com/guide/topics/resources/drawable-resource)).
|
440 |
|
441 | - It should not prevent you from seeing red screen errors.
|
442 |
|
443 | - Hiding the launch screen is configurable: fade it out or hide it without any animation at all (no fade needed if you want to animate it out!).
|