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.
CodePudding user response:
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]);
CodePudding user response:
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.