What's new
Bye AndroidX π
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).
Dark mode π
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!
Brand image support π’
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 π§βπΌ
Web support π
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β¦).
An updated CLI π§βπ»
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 βοΈ
useHideAnimation π«£
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>
);
};
useHideAnimation.usage.mp4
Other changes
- Your Android theme status / navigation bar styles are not overwritten anymore. Guides for transparent status bar and edge-to-edge layouts have been added in the brand new FAQ.
- Android generated assets has been migrated from
mipmap-*
directories todrawable-*
ones. - To avoid conflicts, Android provided theme / properties has been renamed
Theme.BootSplash
/Theme.BootSplash.EdgeToEdge
,bootSplashBackground
,bootSplashLogo
,bootSplashBrand
andpostBootSplashTheme
. - The
duration
argument has been removed fromfade()
options. getVisibilityStatus()
has been replaced withisVisible()
(which returns aPromise<boolean>
). Thetransitioning
status does not exists anymore (when the splash screen is fading, it staysvisible
until complete disappearance).- The CLI now output a
bootsplash_manifest.json
file to share image sizes + colors with the JS thread (used byuseHideAnimation
). --assets-path
CLI option has been renamed--assets-output
.- React Native < 0.70 and iOS < 12.4 support has been dropped.
- ReScript bindings has been removed as I don't know how to write them. Feels free to open a PR to add it back.
Migration
Follow the updated MIGRATION.md