-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Appearance module does not behave correctly: addChangeListener does not react to changes, useColorScheme() does not react to changes. #28823
Comments
Having the same issue here, but it works fine on iOS. For some reason the changeListener never gets called on Android when changing the system color scheme |
Having issues with |
In my case, On iOS it always returns |
Same issue here, works well on iOS but not in Android, changeListener is never called. |
Oh finally I solved the issue for Android. Based on the documentation of the react-native-appearance package I found a configuration for Android that solve this issue. It has to modify the import android.content.Intent; // <--- import
import android.content.res.Configuration; // <--- import
public class MainActivity extends ReactActivity {
......
// copy these lines
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
sendBroadcast(intent);
}
......
} |
@franciscocobas that didn't work for me :/. I create a brand new project and added that method, but it still didn't work. Also @rarira make sure that for iOS, you don't have |
This does seem to fix the issue, make sure uiMode is added in android:configChanges in AndroidManifest.xml also. Thank you for the quick solution :) Edit: This only works when using react-native-appearance. The issue of react-native's Appearance API is still there. |
Thank you @josmithua ... I also have |
Not really, I'm using the react-native's Appearance API. |
I was having the same problem with the hook only returning 'light', no matter how much I'd toggle the appearance in the simulator. After a lot of digging into code, it turned out the reason it was doing this was due to - the debugger! If you're using a Chrome-based debugger (either in browser or using the standalone RN debugger) the Appearance module will always return light, due to the debugger not being able to handle async functions (or something like that, it was a few days ago!). I can't say I understand the idiosyncracies as to why it does this, but the upshot of it all is I stopped using the Chrome debugger and moved to flipper - and it worked! I'm now able to swap between dark and light mode using the useColorTheme hook as expected. Hope this helps someone else, it was a head scratcher for me for quite a while! |
@mvrdrew I use flipper not chrome debugger, but it doesn't work either. @franciscocobas I tried your repo and it works as you mentioned... and you only used react native's API in your code, But I found that in your package.json you have 'react-native-appear' in your dependancies which I don't have. |
While that might be a work around, this issue is to do with React Native's own Appearance module not working correctly. |
To add on to the list of issues. For iOS I've noticed some strange behavior when overriding the Window UserInterfaceStyle natively. From the above gif you can see that setting the system theme works perfect, both the useColorScheme hook and change listener trigger. But if you call Then when you call ^^ this is using the Appearance API from React Native core. If I use the |
Also noticed an issue on the Android side (using e.g. Calling I've raised a PR to address this in |
In terms of getting Android to react to the system theme using the React Native core API, I've got it working by doing the following... // in MainActivity.java
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getReactInstanceManager().onConfigurationChanged(this, newConfig);
} It appears this is some missed implementation in |
Thanks @mrbrentkelly, I can confirm your Android fix works. |
i have same issue, have you solved the problem? |
On my iOS it always returns |
Untill facebook/react-native#28823 will be fixed
Until facebook/react-native#28823 will be fixed
Until facebook/react-native#28823 will be fixed
It doesn't subscribe to changes still. |
For me this works on an ios device with debug mode off. For all other cases (ios device debug mode on, ios simulator, android simulator, android device) this does not seem to work. |
Thanks, @mrbrentkelly! I've confirmed that this manual fix works for me while using the official Appearance API. 🥳 |
I already did a few weeks back :) #29106 |
MainActivity.java import com.facebook.react.ReactActivity;
import android.content.Intent;
import android.content.res.Configuration;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "SQL_PlayGround";
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getReactInstanceManager().onConfigurationChanged(this, newConfig);
}
} The whole code to fix this, hope this gets fixed ASAP |
Doesn't work for me... I'm using react-native-cli not expo and I have still 'dark' from useColorScheme (from react-native and also from react-native-appearance). Where should be call |
@irekrog I've just created a repo that applies the workaround if you want to take a look https://github.com/mrbrentkelly/rn-appearance-workaround. The only code change required to get package com.someproject;
import com.facebook.react.ReactActivity;
import android.content.res.Configuration; // <-- Add this import
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "SomeProject";
}
// Add this code to get Appearance API to work in Android
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getReactInstanceManager().onConfigurationChanged(this, newConfig);
}
} Also make sure you're using an android device or emulator that's running Android 10 or above.
This is more of a RN brownfield scenario so you probably don't need to call this at all. |
Ohh thank you for example repo! :) But now I guess what is wrong because I have a slightly different case. In my app in Settings I have a switcher and I can set dark or light theme for app. For example on my device system theme is dark, but for app I want to change theme to light. Value of theme (dark/light) is saved in Also I have checked with Additionaly I need to manipulate theme in Java with |
@irekrog there's a bug in the appearance API in RN core which will prevent calls to I also fixed the same bug in the So you could ask them to publish the latest changes from their main branch or add e.g.
Note I just tested this all out by creating a bridge module that calls https://github.com/mrbrentkelly/rn-appearance-workaround/compare/BK-WithRNA?expand=1 |
Thank you very very much! :) Yeah, your fix is merged but still not publish to NPM so temporary I have used patch-package to patch react-native-appearance using your fix and it works fine 👍 |
Set initial theme to current device theme Pick this fix facebook/react-native#28823
1) bare workflow recommendations for android dont work ``` public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // dont work // Intent intent = new Intent("onConfigurationChanged"); // intent.putExtra("newConfig", newConfig); // sendBroadcast(intent); // works ideally and already approved by many people in issue facebook/react-native#28823 (comment) getReactInstanceManager().onConfigurationChanged(this, newConfig); } ``` 2) Turned on debugger break `useColorScheme` and `Appearance.getColorScheme` they always return 'light' facebook/react-native#28823 (comment)
Assuming you aren't running into the debugger issue mentioned above, my issue was that the More info here. |
How come more than one year later this hasn't made it into Android yet? |
I was finally merged into main 9 days ago :) When can we expect this to hit the npm packaged release? |
Summary: This PR fixes a few issues with the Appearance API (as noted here #28823). 1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN). 2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context. 3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> ### Fixed #28823 * [Android] [Fixed] - Appearance API now works on Android * [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()` * [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle` Pull Request resolved: #29106 Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url) Reviewed By: hramos Differential Revision: D31284331 Pulled By: sota000 fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
Summary: This PR fixes a few issues with the Appearance API (as noted here #28823). 1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN). 2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context. 3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> ### Fixed #28823 * [Android] [Fixed] - Appearance API now works on Android * [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()` * [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle` Pull Request resolved: #29106 Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url) Reviewed By: hramos Differential Revision: D31284331 Pulled By: sota000 fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
Summary: This PR fixes a few issues with the Appearance API (as noted here #28823). 1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN). 2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context. 3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> ### Fixed #28823 * [Android] [Fixed] - Appearance API now works on Android * [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()` * [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle` Pull Request resolved: #29106 Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url) Reviewed By: hramos Differential Revision: D31284331 Pulled By: sota000 fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
…acebook#29106) Summary: This PR fixes a few issues with the Appearance API (as noted here facebook#28823). 1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN). 2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context. 3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> ### Fixed facebook#28823 * [Android] [Fixed] - Appearance API now works on Android * [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()` * [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle` Pull Request resolved: facebook#29106 Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url) Reviewed By: hramos Differential Revision: D31284331 Pulled By: sota000 fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
Summary: This PR fixes a few issues with the Appearance API (as noted here facebook/react-native#28823). 1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN). 2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context. 3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> ### Fixed facebook/react-native#28823 * [Android] [Fixed] - Appearance API now works on Android * [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()` * [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle` Pull Request resolved: facebook/react-native#29106 Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url) Reviewed By: hramos Differential Revision: D31284331 Pulled By: sota000 fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
Description
The subscription of
useColorScheme()
andAppearance.addChangeListener()
wont work. The hook returns an initial value only on component mount. Changes to the devices color scheme on Android does not provide the hook with a new value. I therefore tried to manually replicate this hook withuseEffect
and theAppearance
module and found thatAppearance.addChangeListener()
when called returns "undefined", not typeEventSubscription
. The listener function provided toAppearance.addChangeListener()
never gets called.I have only tested this on Android so I am not aware if this is also an issue on iOS.
React Native version:
Steps To Reproduce
Provide a detailed list of steps that reproduce the issue.
npx react-native init TestDark --template react-native-template-typescript
Appearance
&useColorScheme
from'react-native'
<App />
or use theuseColorScheme
hook and console.log its output.Expected Results
The
useColorScheme
hook should return the correct colorScheme when the devices colorScheme changes.The
Appearance.addChangeListener()
should return typeEventSubscription
notundefined
.The listener callback provided to Appearance.addChangeListener(cb) should be called.
Snack, code example, screenshot, or link to a repository:
Here is a GIF of the app created with
npx react-native init NAME --template react-native-template-typescript
command. Look for Mode: dark (useColorScheme() and Mode_1 (useEffect & Appearance module). https://gyazo.com/d4ddb35bf689b3c8926be2f613714f73The text was updated successfully, but these errors were encountered: