-
Notifications
You must be signed in to change notification settings - Fork 0
StatusBar
Splash screen jumps on initial load (android prebuild) | Customizing your React Native status bar | StatusBar styles can not be changed using StatusBar component
On android, StatusBar translucent option is adjusted separately for SplashScreen (in app.json androidStatusBar) and for loaded app (using StatusBar from 'react-native'). At the moment of app Screen replaces SplashScreen a layout jump occurs.
StatusBar.pushStackEntry({
barStyle: 'dark-content',
translucent: true,
animated: true,
backgroundColor: 'transparent',
}),
If you call this while SplashScreen visible, SplashScreen leaps. If you call it when app screen is visible — app screen will leap.
To address this issue, I tied the event of adjusting StatusBar to the moment one frame before SplashScreen is replaced by app screen. I've sat SplashScreen "resizeMode": "cover",
so SplashScreen image gets a bit enlarged before it disappears. Something like one frame animation. And it looks better than layout leap when StatusBar become translucent on SplashScreen or app screen.
App.js
const onLayoutRootView = useCallback(async () => {
if (fontsLoaded) {
await delay(
() =>
StatusBar.pushStackEntry({
barStyle: 'dark-content',
translucent: true,
animated: true,
backgroundColor: 'transparent',
}),
2000 // 2 sec delay for loading and render data
);
delay(SplashScreen.hideAsync, 33); // hide SplashScreen one frame after StatusBar gets translucent
}
}, [fontsLoaded]);
if (!fontsLoaded) {
return null;
}
I make use of delay function for delayed execution of callback passed to it.
delay.js
export const delay = (fun, timeout) =>
new Promise((resolve) => setTimeout(resolve, timeout))
.then(fun)
.catch((e) => console.log(e.message));
When I tried to change StatusBar style from 'dark-content' on Posts screen to 'light-content' on Preview Modal, I hadn't been succeeding with commonplace methods. First I wanted to use <StatusBar barStyle="light-content"/>
component. Next I'd tried to manage it by StatusBar.setBarStyle('light-content')
— nothing worked.
I revealed by experiment that only delayed call of StatusBar.setBarStyle('light-content')
has effect with react-native Modal.
const openPreview = async (item) => {
await delay(() => StatusBar.setBarStyle('light-content'), 3);
setPreviewItem(item);
setModalVisible(true);
};
const closePreview = () => {
setModalVisible(false);
delay(() => StatusBar.setBarStyle('dark-content'), 3);
};