Skip to content

Commit

Permalink
Update StatusBar for Android 11+ (#32975)
Browse files Browse the repository at this point in the history
Summary:
Android 11 (API 30) introduced a new interface for changing the appearance of the status bars with [`WindowInsetsController#setSystemBarsAppearance`](https://developer.android.com/reference/kotlin/android/view/WindowInsetsController#setsystembarsappearance) and deprecated using the `WindowManager#systemUiVisibility` properties.

Apparently, once you call `setSystemBarsAppearance` Android will no longer respect `systemUiVisibility` and if anyone, such as the Android 12 Splash Screen library, happens to call it, it will break status bars.

This PR augments the RN StatusBarModule to use the new interface on Android 11+.

Also updated the rn-tester app, see video.

https://user-images.githubusercontent.com/1124321/151321561-8202e237-cf7d-45ce-b957-18b5bafd17c4.mov

## 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
-->

[Android] [Changed] - Use new StatusBar API on Android 11 (API 30)+

Pull Request resolved: #32975

Reviewed By: cortinico

Differential Revision: D33814853

Pulled By: ShikaSD

fbshipit-source-id: c0f2651015dddb4871a3e3b26642f76a46da2a76
  • Loading branch information
ieatfood authored and facebook-github-bot committed Jan 31, 2022
1 parent c1bb945 commit 50c8e97
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.os.Build;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
Expand Down Expand Up @@ -184,12 +185,23 @@ public void setStyle(@Nullable final String style) {
return;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
UiThreadUtil.runOnUiThread(
new Runnable() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void run() {
UiThreadUtil.runOnUiThread(
new Runnable() {
@TargetApi(Build.VERSION_CODES.R)
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowInsetsController insetsController = activity.getWindow().getInsetsController();
if ("dark-content".equals(style)) {
// dark-content means dark icons on a light status bar
insetsController.setSystemBarsAppearance(
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
} else {
insetsController.setSystemBarsAppearance(
0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decorView = activity.getWindow().getDecorView();
int systemUiVisibilityFlags = decorView.getSystemUiVisibility();
if ("dark-content".equals(style)) {
Expand All @@ -199,7 +211,7 @@ public void run() {
}
decorView.setSystemUiVisibility(systemUiVisibilityFlags);
}
});
}
}
});
}
}
43 changes: 40 additions & 3 deletions packages/rn-tester/js/examples/StatusBar/StatusBarExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const {

const colors = ['#ff0000', '#00ff00', '#0000ff', 'rgba(0, 0, 0, 0.4)'];

const barStyles = ['default', 'light-content'];
const barStyles = ['default', 'light-content', 'dark-content'];

const showHideTransitions = ['fade', 'slide'];

Expand Down Expand Up @@ -129,11 +129,16 @@ class StatusBarStyleExample extends React.Component<{...}, $FlowFixMeState> {
<Text>style: '{getValue(barStyles, this._barStyleIndex)}'</Text>
</View>
</TouchableHighlight>
<View style={styles.wrapper}>
<Text>(default is dark for iOS, light for Android)</Text>
</View>
<TouchableHighlight
style={styles.wrapper}
onPress={this._onChangeAnimated}>
<View style={styles.button}>
<Text>animated: {this.state.animated ? 'true' : 'false'}</Text>
<Text>
animated (ios only): {this.state.animated ? 'true' : 'false'}
</Text>
</View>
</TouchableHighlight>
</View>
Expand Down Expand Up @@ -288,6 +293,9 @@ class StatusBarStaticIOSExample extends React.Component<{...}> {
<Text>setBarStyle('default', true)</Text>
</View>
</TouchableHighlight>
<View style={styles.wrapper}>
<Text>(default is dark for iOS, light for Android)</Text>
</View>
<TouchableHighlight
style={styles.wrapper}
onPress={() => {
Expand Down Expand Up @@ -342,6 +350,36 @@ class StatusBarStaticAndroidExample extends React.Component<{...}> {
<Text>setHidden(false)</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
onPress={() => {
StatusBar.setBarStyle('light-content');
}}>
<View style={styles.button}>
<Text>setBarStyle('light-content')</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
onPress={() => {
StatusBar.setBarStyle('dark-content');
}}>
<View style={styles.button}>
<Text>setBarStyle('dark-content')</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
onPress={() => {
StatusBar.setBarStyle('default');
}}>
<View style={styles.button}>
<Text>setBarStyle('default')</Text>
</View>
</TouchableHighlight>
<View style={styles.wrapper}>
<Text>(default is dark for iOS, light for Android)</Text>
</View>
<TouchableHighlight
style={styles.wrapper}
onPress={() => {
Expand Down Expand Up @@ -448,7 +486,6 @@ exports.examples = [
render(): React.Node {
return <StatusBarStyleExample />;
},
platform: 'ios',
},
{
title: 'StatusBar network activity indicator',
Expand Down

0 comments on commit 50c8e97

Please sign in to comment.