React Native Appearance.addChangeListener() does nothing

4.4k views Asked by At

I am writing my first react-native app and would like to switch themes like GMail does.
Indeed GMail get darker colors when we change the theme mode, or set automatic dark theme during nights, into the phone settings.
So I try to implement the Appearance.addChangeListener as explained in the doc but unfortunately the feature doesn't work.

I am trying on Android 10.

How can I, without restarting the app, update the color of my application when the phone theme change ?

useEffect(() => {
    dispatch(changeTheme(Appearance.getColorScheme()));
    Appearance.addChangeListener(onThemeChange);

    return () => Appearance.removeChangeListener(onThemeChange);
}, []);

// This function is never call
const onThemeChange = ({ colorScheme }) => {
    console.log("onThemeChange", colorScheme)
    dispatch(changeTheme(colorScheme));
}

3

There are 3 answers

2
Mahmonir Bakhtiyari On

I resolved this problem by adding this code to MainActivity.java:

import android.content.res.Configuration;
    
@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  getReactInstanceManager().onConfigurationChanged(this, newConfig);
}

and for testing this feature, you can change DarkTheme in Android 10 and above ON/OFF.

0
Alireza Goudarzi On

useColorScheme

you can use useColorScheme, it will update automatically.

first

import {useColorScheme} from 'react-native;

then, in you functional component

const colorScheme = useColorScheme();

I also suggest to write your own custom hook to update StatusBar and NavigationBar on colorScheme changed

0
Sayan Dey On

use useColorScheme

It will change the dark and light mode automatically

import {useColorScheme} from 'react-native;

then,for class component

componentDidMount() {
    Appearance.getColorScheme()=='dark'?this.setState({ theme: true }): this.setState({ theme: false});

  }
 componentDidUpdate(){
    this.listener =Appearance.addChangeListener((theme) => {
      // console.log("theme", theme);
      theme.colorScheme == "dark"
        ? this.setState({ theme: true })
        : this.setState({ theme: false });
    });

  }