简体   繁体   中英

React Native - How to reload colors based on Dark Mode and Light Mode

We have been trying to implement dark mode in an old project, where we have some colors defined in a separate file and been used throughout the application something like mentioned below

import {Appearance} from "react-native";

const isDarkMode = (Appearance.getColorScheme() === 'dark')

const Color = {
    WHITE: '#FFFFFF',
    TRANSPARENT: 'transparent',
    THEMECOLOR: isDarkMode ? '#1A252F' : '#25A31D',
    THEMEBLACK: isDarkMode ? '#121B24' : '#252525',
    THEMEDARKGREEN: isDarkMode ? '#2F3F4D' : '#407F2C',
    THEMEWHITE: isDarkMode ? '#121B24' : '#FFFFFF',
    TXTGREETING: isDarkMode ? '#898989' : 'rgba(0, 0, 0, .5)',
    TXTWHITE: isDarkMode ? '#8A8A8A' : '#FFFFFF',
    TXTTHEME: isDarkMode ? '#676C69' : '#25A31D',
    TXTGREY: isDarkMode ? '#676C69' : '#9E9E9E',
    TXTDARKGREY: isDarkMode ? '#505050' : '#9E9E9E',
    TXTBLACK: isDarkMode ? '#676c69' : '#252525',
}

export default { Color };

It is used as shown below

import appColors from "common/colors";

export default StyleSheet.create({
    container:{
        flex:1,
        backgroundColor: appColors.Color.THEMECOLOR,
    }
});

We don't have any internal feature to switch to the Dark Mode inside the app, but it should work if changed from Device settings, which does work well but it requires killing the app and restarting.

It doesn't work when the app is running, though we have tried to infuse themes in NavigationContainer

import { NavigationContainer,DarkTheme,DefaultTheme } from "@react-navigation/native";
render() {
    return (
      <NavigationContainer theme={isDarkMode?DarkTheme:DefaultTheme}>
        <RootStackScreen screenProps={this.props} />
      </NavigationContainer>
    )
}

How to achieve this when the app is running and the Dark Mode is changed from device settings?

Thanks for any pointers.

I had the same problem and solve it with the code bellow:

const [colorScheme,setColorScheme] = useState(() => Appearance.getColorScheme());

const handleColorScheme = useCallback((theme) => {
  setColorScheme(theme.colorScheme);
}, []);

useEffect(() => {
  Appearance.addChangeListener(handleColorScheme);
  return () => {
    Appearance.removeChangeListener(handleColorScheme);
  };
}, [handleColorScheme]);

What Arthur does is correct. What you also could do for manual switching, is adding a button that writes 'light' and 'dark' to an ASync Storage and then read the values and load it before the render.

At least, that's what I am doing! So even manual buttons are possible for sure. I have done so, because a big part of our userbase uses older phones.

Typically Arthurs code goes at the file that has the Navigation Stack inside it. If you have a one page app, you should load it at the home screen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM