Skip to content

StatusBar

andreiradchenko edited this page Apr 30, 2024 · 2 revisions

StatusBar

Splash screen jumps on initial load (android prebuild) | Customizing your React Native status bar | StatusBar styles can not be changed using StatusBar component

StatusBar on initial load

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));

Adjust StatusBar barStyle on Modal

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);
};