Skip to content

Commit 50c8e97

Browse files
ieatfoodfacebook-github-bot
authored andcommitted
Update StatusBar for Android 11+ (#32975)
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
1 parent c1bb945 commit 50c8e97

File tree

2 files changed

+60
-11
lines changed

2 files changed

+60
-11
lines changed

ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.java

+20-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import android.os.Build;
1616
import android.view.View;
1717
import android.view.WindowInsets;
18+
import android.view.WindowInsetsController;
1819
import android.view.WindowManager;
1920
import androidx.annotation.Nullable;
2021
import androidx.core.view.ViewCompat;
@@ -184,12 +185,23 @@ public void setStyle(@Nullable final String style) {
184185
return;
185186
}
186187

187-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
188-
UiThreadUtil.runOnUiThread(
189-
new Runnable() {
190-
@TargetApi(Build.VERSION_CODES.M)
191-
@Override
192-
public void run() {
188+
UiThreadUtil.runOnUiThread(
189+
new Runnable() {
190+
@TargetApi(Build.VERSION_CODES.R)
191+
@Override
192+
public void run() {
193+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
194+
WindowInsetsController insetsController = activity.getWindow().getInsetsController();
195+
if ("dark-content".equals(style)) {
196+
// dark-content means dark icons on a light status bar
197+
insetsController.setSystemBarsAppearance(
198+
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
199+
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
200+
} else {
201+
insetsController.setSystemBarsAppearance(
202+
0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
203+
}
204+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
193205
View decorView = activity.getWindow().getDecorView();
194206
int systemUiVisibilityFlags = decorView.getSystemUiVisibility();
195207
if ("dark-content".equals(style)) {
@@ -199,7 +211,7 @@ public void run() {
199211
}
200212
decorView.setSystemUiVisibility(systemUiVisibilityFlags);
201213
}
202-
});
203-
}
214+
}
215+
});
204216
}
205217
}

packages/rn-tester/js/examples/StatusBar/StatusBarExample.js

+40-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const {
2323

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

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

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

@@ -129,11 +129,16 @@ class StatusBarStyleExample extends React.Component<{...}, $FlowFixMeState> {
129129
<Text>style: '{getValue(barStyles, this._barStyleIndex)}'</Text>
130130
</View>
131131
</TouchableHighlight>
132+
<View style={styles.wrapper}>
133+
<Text>(default is dark for iOS, light for Android)</Text>
134+
</View>
132135
<TouchableHighlight
133136
style={styles.wrapper}
134137
onPress={this._onChangeAnimated}>
135138
<View style={styles.button}>
136-
<Text>animated: {this.state.animated ? 'true' : 'false'}</Text>
139+
<Text>
140+
animated (ios only): {this.state.animated ? 'true' : 'false'}
141+
</Text>
137142
</View>
138143
</TouchableHighlight>
139144
</View>
@@ -288,6 +293,9 @@ class StatusBarStaticIOSExample extends React.Component<{...}> {
288293
<Text>setBarStyle('default', true)</Text>
289294
</View>
290295
</TouchableHighlight>
296+
<View style={styles.wrapper}>
297+
<Text>(default is dark for iOS, light for Android)</Text>
298+
</View>
291299
<TouchableHighlight
292300
style={styles.wrapper}
293301
onPress={() => {
@@ -342,6 +350,36 @@ class StatusBarStaticAndroidExample extends React.Component<{...}> {
342350
<Text>setHidden(false)</Text>
343351
</View>
344352
</TouchableHighlight>
353+
<TouchableHighlight
354+
style={styles.wrapper}
355+
onPress={() => {
356+
StatusBar.setBarStyle('light-content');
357+
}}>
358+
<View style={styles.button}>
359+
<Text>setBarStyle('light-content')</Text>
360+
</View>
361+
</TouchableHighlight>
362+
<TouchableHighlight
363+
style={styles.wrapper}
364+
onPress={() => {
365+
StatusBar.setBarStyle('dark-content');
366+
}}>
367+
<View style={styles.button}>
368+
<Text>setBarStyle('dark-content')</Text>
369+
</View>
370+
</TouchableHighlight>
371+
<TouchableHighlight
372+
style={styles.wrapper}
373+
onPress={() => {
374+
StatusBar.setBarStyle('default');
375+
}}>
376+
<View style={styles.button}>
377+
<Text>setBarStyle('default')</Text>
378+
</View>
379+
</TouchableHighlight>
380+
<View style={styles.wrapper}>
381+
<Text>(default is dark for iOS, light for Android)</Text>
382+
</View>
345383
<TouchableHighlight
346384
style={styles.wrapper}
347385
onPress={() => {
@@ -448,7 +486,6 @@ exports.examples = [
448486
render(): React.Node {
449487
return <StatusBarStyleExample />;
450488
},
451-
platform: 'ios',
452489
},
453490
{
454491
title: 'StatusBar network activity indicator',

0 commit comments

Comments
 (0)