π Show a splash screen during app startup. Hide it when you are ready.
MIT License
Bot releases are visible (Hide)
Published by zoontek about 1 year ago
v4 introduced the usage of the official Android SplashScreen API with androidx.core:core-splashscreen
in order to support Android 12+. But this change came with a lot of issues (#381, #418, #440, #456, etc.), and those issues seem to be ignored on the Google issue tracker. The next version now uses its own polyfill, compatible with Android 5+ (without any degraded mode, compared to the AndroidX one).
The generator is now able to output a lot more files, including dark mode versions of all the splash screen assets (in all required pixel densities, but also config files, etc.)
The update is simple: run the generator, drag and drop the newly created Colors.xcassets
in your Xcode project, done!
Dropping AndroidX was also necessary to add brand images support on Android 5+ as the feature wasn't polyfilled (and android:windowSplashScreenBrandingImage
is only available on Android 12+).
You can finally tell your boss that the company logo will be visible at app opening π§βπΌ
The generator will now look for a index.html
file in you project (or the file you specify using the new --html
option) and update it in place. All existing features are supported (brand image, dark mode, animationβ¦).
In order to support all these new features, I had to publish an updated CLI generator. By default, it will be as capable as the previous one (android, iOS and the assets directory). The only new emitted file is the manifest (for useHideAnimation
usage). But in order to to use the --brand
, --brand-width
and --dark-*
options, you must specify a --license-key
π
With it, the generator is able to output over 50 files (logo and brand images generated in all pixel densities, dark mode versions, etc.), saving you (and your company!) a massive amount of time not only at creation, but also at each adjustment.
Usage: react-native generate-bootsplash [options] <logo>
Generate a launch screen using a logo file path (PNG or SVG)
Options:
--platforms <list> Platforms to generate for, separated by a comma (default: "android,ios,web")
--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
--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: "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
I know, free software is always better. But I think it's a good way to make the development of this library (and indirectly, react-native-permissions
and react-native-localize
) sustainable.
Monetizing open source is a hard task and I'm really glad a few individuals and companies are sponsoring my work, but unfortunately it's not systematic yet for companies to give a bit, even if their products are often built using free open source maintainers work.
βοΈ Important: If you are currently sponsoring me, or sponsored me once in the past, contact me to get a free license key. It could have been any amount, even only 1$ for a coffee βοΈ
You always wanted a custom hide animation, similar to the one in the example project? useHideAnimation
is a new hook that will help you creating one, in the easiest way possible.
How does it work? First, run the generator with the --assets-output
option. Once the files are ready, create a custom splash screen:
const AnimatedBootSplash = ({ onAnimationEnd }: { onAnimationEnd: () => void }) => {
const [opacity] = useState(() => new Animated.Value(1));
const [translateY] = useState(() => new Animated.Value(0));
// note that you can also animate the brand image (check the documentation)
const { container, logo } = BootSplash.useHideAnimation({
// the manifest file is generated when --assets-output is specified
// it includes colors and computed sizes values
manifest: require("../assets/bootsplash_manifest.json"),
// the required generated assets
logo: require("../assets/bootsplash_logo.png"),
darkLogo: require("../assets/bootsplash_dark_logo.png"),
// specify if you are using translucent status / navigation bars
// in order to avoid a shift between the native and JS splash screen
statusBarTranslucent: true,
navigationBarTranslucent: false,
// run animations. the call to hide() will be done automatically
// you can use Animated, but also react-native-reanimated, etc.
animate: () => {
const { height } = Dimensions.get("window");
Animated.stagger(250, [
Animated.spring(translateY, {
toValue: -50,
useNativeDriver: true,
}),
Animated.spring(translateY, {
toValue: height,
useNativeDriver: true,
}),
]).start();
Animated.timing(opacity, {
toValue: 0,
duration: 150,
delay: 350,
useNativeDriver: true,
}).start(() => {
onAnimationEnd();
});
},
});
return (
<Animated.View {...container} style={[container.style, { opacity }]}>
<Animated.Image
{...logo}
style={[logo.style, { transform: [{ translateY }] }]}
/>
</Animated.View>
);
};
Then uses it:
const App = () => {
const [visible, setVisible] = useState(true);
return (
<View style={{ flex: 1 }}>
{/* content */}
{visible && (
<AnimatedBootSplash
onAnimationEnd={() => {
setVisible(false);
}}
/>
)}
</View>
);
};
mipmap-*
directories to drawable-*
ones.Theme.BootSplash
/ Theme.BootSplash.EdgeToEdge
, bootSplashBackground
, bootSplashLogo
, bootSplashBrand
and postBootSplashTheme
.duration
argument has been removed from fade()
options.getVisibilityStatus()
has been replaced with isVisible()
(which returns a Promise<boolean>
). The transitioning
status does not exists anymore (when the splash screen is fading, it stays visible
until complete disappearance).bootsplash_manifest.json
file to share image sizes + colors with the JS thread (used by useHideAnimation
).--assets-path
CLI option has been renamed --assets-output
.Follow the updated MIGRATION.md
Published by zoontek over 1 year ago
Published by zoontek over 1 year ago
sharp
to fix autolinking when it cannot be installed + provide insightful error in the generatornamespace
conditionally in order to improve old react native version compatibility.Published by zoontek over 1 year ago
--assets-path
directory if it doesn't exist--platforms
error reportingPublished by zoontek over 1 year ago
Published by zoontek over 1 year ago
Note that the iOS setup has been updated for react-native
>= 0.71
.
The old way still works, but this is the preferred one now:
#import "AppDelegate.h"
#import "RNBootSplash.h"
#import <React/RCTBundleURLProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"YourAppName";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
// βοΈ Remove the initWithStoryboard call here and restore the original returned value
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// β¦
// β¬οΈ Add this before file @end
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initProps:(NSDictionary *)initProps {
UIView *rootView = [super createRootViewWithBridge:bridge
moduleName:moduleName
initProps:initProps];
[RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView]; // β¬
οΈ initialize the splash screen
return rootView;
}
@end
Published by zoontek over 1 year ago
--platforms
CLI argument to generate assets only for a subset of platforms (only android, or only ios) (#441 by @nazmeln)Published by zoontek over 1 year ago
Published by zoontek over 1 year ago
Published by zoontek over 1 year ago
Published by zoontek over 1 year ago
jimp
to sharp
in order to add svg input file support (https://github.com/zoontek/react-native-bootsplash/pull/426)Published by zoontek over 1 year ago
Published by zoontek almost 2 years ago
Published by zoontek almost 2 years ago
Published by zoontek almost 2 years ago
jimp
to 0.16.1
, resolving CVE-2022-25851 (#396 by @conceptualspace)Published by zoontek about 2 years ago
postinstall
(https://github.com/zoontek/react-native-bootsplash/commit/546b2aa500672d18937d1cace748ad65b72befd0, fix #384)Published by zoontek about 2 years ago
onCreate
instead of loadApp
to init react-native-bootsplash
as soon as possible (fix #379):import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
+ import android.os.Bundle;
import com.zoontek.rnbootsplash.RNBootSplash;
public class MainActivity extends ReactActivity {
// β¦
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ RNBootSplash.init(this); // <- initialize the splash screen
+ super.onCreate(savedInstanceState); // or super.onCreate(null) with react-native-screens
+ }
public static class MainActivityDelegate extends ReactActivityDelegate {
// β¦
- @Override
- protected void loadApp(String appKey) {
- RNBootSplash.init(getPlainActivity()); // <- initialize the splash screen
- super.loadApp(appKey);
- }
}
}
Published by zoontek about 2 years ago
core-splashscreen
package to 1.0.0
Update the package accordingly in your android/app/build.gradle
file:
// β¦
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
+ implementation "androidx.core:core-splashscreen:1.0.0"
Published by zoontek about 2 years ago
ios
folder does not exists (Fix #377)