diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/StatusBar.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/StatusBar.java index 5441a16e88..525183301d 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/StatusBar.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/StatusBar.java @@ -16,6 +16,13 @@ @NativePlugin() public class StatusBar extends Plugin { + private int currentStatusbarColor; + + public void load() { + // save initial color of the status bar + currentStatusbarColor = getActivity().getWindow().getStatusBarColor(); + } + @PluginMethod() public void setStyle(final PluginCall call) { final String style = call.getString("style"); @@ -57,7 +64,10 @@ public void run() { window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); try { - window.setStatusBarColor(Color.parseColor(color.toUpperCase())); + final int parsedColor = Color.parseColor(color.toUpperCase()); + window.setStatusBarColor(parsedColor); + // update the local color field as well + currentStatusbarColor = parsedColor; call.success(); } catch (IllegalArgumentException ex) { call.error("Invalid color provided. Must be a hex string (ex: #ff0000"); @@ -114,6 +124,38 @@ public void getInfo(final PluginCall call) { data.put("visible", (decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_FULLSCREEN) != View.SYSTEM_UI_FLAG_FULLSCREEN); data.put("style", style); data.put("color", String.format("#%06X", (0xFFFFFF & window.getStatusBarColor()))); + data.put("overlays", (decorView.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); call.resolve(data); } + + @PluginMethod() + public void setOverlaysWebView(final PluginCall call) { + final Boolean overlays = call.getBoolean("overlay", true); + getBridge().executeOnMainThread(new Runnable() { + @Override + public void run() { + if (overlays) { + // Sets the layout to a fullscreen one that does not hide the actual status bar, so the webview is displayed behind it. + View decorView = getActivity().getWindow().getDecorView(); + int uiOptions = decorView.getSystemUiVisibility(); + uiOptions = uiOptions | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + decorView.setSystemUiVisibility(uiOptions); + currentStatusbarColor = getActivity().getWindow().getStatusBarColor(); + getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT); + + call.success(); + } else { + // Sets the layout to a normal one that displays the webview below the status bar. + View decorView = getActivity().getWindow().getDecorView(); + int uiOptions = decorView.getSystemUiVisibility(); + uiOptions = uiOptions & ~View.SYSTEM_UI_FLAG_LAYOUT_STABLE & ~View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + decorView.setSystemUiVisibility(uiOptions); + // recover the previous color of the status bar + getActivity().getWindow().setStatusBarColor(currentStatusbarColor); + + call.success(); + } + } + }); + } } diff --git a/core/src/core-plugin-definitions.ts b/core/src/core-plugin-definitions.ts index 9d6fbd0095..9b7df56785 100644 --- a/core/src/core-plugin-definitions.ts +++ b/core/src/core-plugin-definitions.ts @@ -1608,6 +1608,11 @@ export interface StatusBarPlugin extends Plugin { * Get info about the current state of the status bar */ getInfo(): Promise; + /** + * Set whether or not the status bar should overlay the webview to allow usage of the space + * around a device "notch" + */ + setOverlaysWebView(options: StatusBarOverlaysWebviewOptions): Promise; } export interface StatusBarStyleOptions { @@ -1633,6 +1638,11 @@ export interface StatusBarInfoResult { visible: boolean; style: StatusBarStyle; color?: string; + overlays?: boolean; +} + +export interface StatusBarOverlaysWebviewOptions { + overlay: boolean; } export interface StoragePlugin extends Plugin { diff --git a/ios/Capacitor/Capacitor/Plugins/DefaultPlugins.m b/ios/Capacitor/Capacitor/Plugins/DefaultPlugins.m index 4a0342394a..305fa45126 100644 --- a/ios/Capacitor/Capacitor/Plugins/DefaultPlugins.m +++ b/ios/Capacitor/Capacitor/Plugins/DefaultPlugins.m @@ -139,6 +139,7 @@ CAP_PLUGIN_METHOD(show, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(hide, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(getInfo, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(setOverlaysWebView, CAPPluginReturnPromise); ) CAP_PLUGIN(CAPStoragePlugin, "Storage", diff --git a/ios/Capacitor/Capacitor/Plugins/StatusBar.swift b/ios/Capacitor/Capacitor/Plugins/StatusBar.swift index f13fb98c2e..cb585bd3b5 100644 --- a/ios/Capacitor/Capacitor/Plugins/StatusBar.swift +++ b/ios/Capacitor/Capacitor/Plugins/StatusBar.swift @@ -75,5 +75,9 @@ public class CAPStatusBarPlugin: CAPPlugin { ]) } } + + @objc func setOverlaysWebView(_ call: CAPPluginCall) { + call.unimplemented() + } } diff --git a/site/docs-md/apis/status-bar/index.md b/site/docs-md/apis/status-bar/index.md index f4f969e9c4..1b4cb9bd78 100644 --- a/site/docs-md/apis/status-bar/index.md +++ b/site/docs-md/apis/status-bar/index.md @@ -49,6 +49,11 @@ export class StatusBarExample { style: this.isStatusBarLight ? StatusBarStyle.Dark : StatusBarStyle.Light }); this.isStatusBarLight = !this.isStatusBarLight; + + // Display content under transparent status bar (Android only) + Statusbar.setOverlaysWebView({ + overlay: true + }); } hideStatusBar() {