mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix an issue where the status bar colors would not match when opening modals (#40979)
Summary: The current ReactModalHostView implementation incorrectly applies system bar appearances by providing the wrong mask to the `setSystemBarsAppearance` method invocation. Per [this issue comment](https://github.com/facebook/react-native/issues/34350#issuecomment-1760339877), jaydonlau correctly identified that when the status bar is set to `light-content` (light icons, dark background), the function is called with both a `0` appearance and `0` mask, which should instead be provided with the `APPEARANCE_LIGHT_STATUS_BARS` mask. The first pass at this PR attempted to pull out the entire appearance from the activity, compare it against the dialog's appearance, and only use a mask of differing bits (see the `appearanceMask` variable). However, if the `android:windowLightStatusBar` attribute is ever set to true, this does not impact the appearance of the status bar but rather the system UI visibility. As a result, the derived mask from system bars appearance would be 0 since both the activity and dialog would have appearances of 0. Rather than try and "future-proof" this implementation for other uses of system bar appearance, this change is directed only at updating the `APPEARANCE_LIGHT_STATUS_BARS` bit in the dialog's system bar appearance. The only other native code that touches status bars is the `StatusBarModule` and that only touches this flag. This is a follow-up to https://github.com/facebook/react-native/issues/34899. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [ANDROID] [FIXED] - Fixed an issue where the status bar colors would not match when opening modals Pull Request resolved: https://github.com/facebook/react-native/pull/40979 Test Plan: First test: - Replace the `RNTesterAppShared` implementation with the implementation from [this Expo snack](https://snack.expo.dev/abbondanzo/status-bar-tester) - Toggle the status bar to show dark icons, open the modal and ensure that dark icons are displayed - Toggle the status bar to show light icons, open the modal and ensure that light icons are displayed Second test: - Set the `android:windowLightStatusBar` attribute to true in the `AppTheme` - Follow the steps from the First test above, guaranteeing that status bar appearance overrides the theme Reviewed By: NickGerleman Differential Revision: D50329714 Pulled By: luluwu2032 fbshipit-source-id: 26ecaca05f8e00a52e13767e468b552ac167fc98
This commit is contained in:
committed by
Facebook GitHub Bot
parent
dd694ec22e
commit
e8d622e9d1
+28
-13
@@ -19,6 +19,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStructure;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -328,19 +329,7 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListe
|
||||
}
|
||||
if (currentActivity != null && !currentActivity.isFinishing()) {
|
||||
mDialog.show();
|
||||
if (context instanceof Activity) {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
|
||||
int appearance =
|
||||
((Activity) context).getWindow().getInsetsController().getSystemBarsAppearance();
|
||||
mDialog.getWindow().getInsetsController().setSystemBarsAppearance(appearance, appearance);
|
||||
} else {
|
||||
mDialog
|
||||
.getWindow()
|
||||
.getDecorView()
|
||||
.setSystemUiVisibility(
|
||||
((Activity) context).getWindow().getDecorView().getSystemUiVisibility());
|
||||
}
|
||||
}
|
||||
updateSystemAppearance();
|
||||
mDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
}
|
||||
}
|
||||
@@ -394,6 +383,32 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListe
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSystemAppearance() {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
if (currentActivity == null) {
|
||||
return;
|
||||
}
|
||||
Assertions.assertNotNull(mDialog, "mDialog must exist when we call updateSystemAppearance");
|
||||
// Modeled after the version check in StatusBarModule.setStyle
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
|
||||
int activityAppearance =
|
||||
currentActivity.getWindow().getInsetsController().getSystemBarsAppearance();
|
||||
int activityLightStatusBars =
|
||||
activityAppearance & WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
|
||||
mDialog
|
||||
.getWindow()
|
||||
.getInsetsController()
|
||||
.setSystemBarsAppearance(
|
||||
activityLightStatusBars, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
|
||||
} else {
|
||||
mDialog
|
||||
.getWindow()
|
||||
.getDecorView()
|
||||
.setSystemUiVisibility(
|
||||
currentActivity.getWindow().getDecorView().getSystemUiVisibility());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public StateWrapper getStateWrapper() {
|
||||
return mHostView.getStateWrapper();
|
||||
|
||||
Reference in New Issue
Block a user