Skip to content

Commit 3834571

Browse files
mrbrentkellybrentvatne
authored andcommitted
Addressing various issues with the Appearance API (facebook#28823) (facebook#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
1 parent 00f4191 commit 3834571

5 files changed

Lines changed: 27 additions & 14 deletions

File tree

React/CoreModules/RCTAppearance.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ - (dispatch_queue_t)methodQueue
8989

9090
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getColorScheme)
9191
{
92-
_currentColorScheme = RCTColorSchemePreference(nil);
92+
if (_currentColorScheme == nil) {
93+
_currentColorScheme = RCTColorSchemePreference(nil);
94+
}
9395
return _currentColorScheme;
9496
}
9597

ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package com.facebook.react;
99

1010
import android.content.Intent;
11+
import android.content.res.Configuration;
1112
import android.os.Bundle;
1213
import android.view.KeyEvent;
1314
import androidx.annotation.Nullable;
@@ -120,6 +121,12 @@ public void onWindowFocusChanged(boolean hasFocus) {
120121
mDelegate.onWindowFocusChanged(hasFocus);
121122
}
122123

124+
@Override
125+
public void onConfigurationChanged(Configuration newConfig) {
126+
super.onConfigurationChanged(newConfig);
127+
mDelegate.onConfigurationChanged(newConfig);
128+
}
129+
123130
protected final ReactNativeHost getReactNativeHost() {
124131
return mDelegate.getReactNativeHost();
125132
}

ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import android.app.Activity;
1212
import android.content.Context;
1313
import android.content.Intent;
14+
import android.content.res.Configuration;
1415
import android.os.Build;
1516
import android.os.Bundle;
1617
import android.view.KeyEvent;
@@ -154,6 +155,12 @@ public void onWindowFocusChanged(boolean hasFocus) {
154155
}
155156
}
156157

158+
public void onConfigurationChanged(Configuration newConfig) {
159+
if (getReactNativeHost().hasInstance()) {
160+
getReactInstanceManager().onConfigurationChanged(getContext(), newConfig);
161+
}
162+
}
163+
157164
@TargetApi(Build.VERSION_CODES.M)
158165
public void requestPermissions(
159166
String[] permissions, int requestCode, PermissionListener listener) {

ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package com.facebook.react.modules.appearance;
99

10+
import android.app.Activity;
1011
import android.content.Context;
1112
import android.content.res.Configuration;
1213
import androidx.annotation.Nullable;
@@ -90,7 +91,15 @@ public String getName() {
9091

9192
@Override
9293
public String getColorScheme() {
93-
mColorScheme = colorSchemeForCurrentConfiguration(getReactApplicationContext());
94+
// Attempt to use the Activity context first in order to get the most up to date
95+
// scheme. This covers the scenario when AppCompatDelegate.setDefaultNightMode()
96+
// is called directly (which can occur in Brownfield apps for example).
97+
Activity activity = getCurrentActivity();
98+
99+
mColorScheme =
100+
colorSchemeForCurrentConfiguration(
101+
activity != null ? activity : getReactApplicationContext());
102+
94103
return mColorScheme;
95104
}
96105

packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77

88
package com.facebook.react.uiapp;
99

10-
import android.content.res.Configuration;
1110
import android.os.Bundle;
1211
import androidx.annotation.Nullable;
1312
import com.facebook.react.ReactActivity;
1413
import com.facebook.react.ReactActivityDelegate;
15-
import com.facebook.react.ReactInstanceManager;
1614
import com.facebook.react.ReactRootView;
1715

1816
public class RNTesterActivity extends ReactActivity {
@@ -64,14 +62,4 @@ protected ReactActivityDelegate createReactActivityDelegate() {
6462
protected String getMainComponentName() {
6563
return "RNTesterApp";
6664
}
67-
68-
@Override
69-
public void onConfigurationChanged(Configuration newConfig) {
70-
super.onConfigurationChanged(newConfig);
71-
ReactInstanceManager instanceManager = getReactInstanceManager();
72-
73-
if (instanceManager != null) {
74-
instanceManager.onConfigurationChanged(this, newConfig);
75-
}
76-
}
7765
}

0 commit comments

Comments
 (0)