Skip to content

Commit

Permalink
feat(statusbar): implement overlay and background color in iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
andredestro committed Aug 22, 2024
1 parent 4fa3245 commit f6d9794
Show file tree
Hide file tree
Showing 13 changed files with 424 additions and 70 deletions.
15 changes: 4 additions & 11 deletions status-bar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ The status bar visibility defaults to visible and the style defaults to
`Style.Default`. You can change these defaults by adding
`UIStatusBarHidden` and/or `UIStatusBarStyle` in `Info.plist`.

`setBackgroundColor` and `setOverlaysWebView` are currently not supported on
iOS devices.

## Example

```typescript
Expand All @@ -33,7 +30,7 @@ window.addEventListener('statusTap', function () {
console.log('statusbar tapped');
});

// Display content under transparent status bar (Android only)
// Display content under transparent status bar
StatusBar.setOverlaysWebView({ overlay: true });

const setStatusBarStyleDark = async () => {
Expand Down Expand Up @@ -96,8 +93,6 @@ setBackgroundColor(options: BackgroundColorOptions) => Promise<void>

Set the background color of the status bar.

This method is only supported on Android.

| Param | Type |
| ------------- | ------------------------------------------------------------------------- |
| **`options`** | <code><a href="#backgroundcoloroptions">BackgroundColorOptions</a></code> |
Expand Down Expand Up @@ -169,8 +164,6 @@ setOverlaysWebView(options: SetOverlaysWebViewOptions) => Promise<void>
Set whether or not the status bar should overlay the webview to allow usage
of the space underneath it.

This method is only supported on Android.

| Param | Type |
| ------------- | ------------------------------------------------------------------------------- |
| **`options`** | <code><a href="#setoverlayswebviewoptions">SetOverlaysWebViewOptions</a></code> |
Expand All @@ -194,7 +187,7 @@ This method is only supported on Android.

| Prop | Type | Description | Since |
| ----------- | ------------------- | ------------------------------------------------------------------------------------------- | ----- |
| **`color`** | <code>string</code> | A hex color to which the status bar color is set. This option is only supported on Android. | 1.0.0 |
| **`color`** | <code>string</code> | A hex color to which the status bar color is set. | 1.0.0 |


#### AnimationOptions
Expand All @@ -210,8 +203,8 @@ This method is only supported on Android.
| -------------- | --------------------------------------- | ----------------------------------------------------------------------------------- | ----- |
| **`visible`** | <code>boolean</code> | Whether the status bar is visible or not. | 1.0.0 |
| **`style`** | <code><a href="#style">Style</a></code> | The current status bar style. | 1.0.0 |
| **`color`** | <code>string</code> | The current status bar color. This option is only supported on Android. | 1.0.0 |
| **`overlays`** | <code>boolean</code> | Whether the statusbar is overlaid or not. This option is only supported on Android. | 1.0.0 |
| **`color`** | <code>string</code> | The current status bar color. | 1.0.0 |
| **`overlays`** | <code>boolean</code> | Whether the statusbar is overlaid or not. | 1.0.0 |


#### SetOverlaysWebViewOptions
Expand Down
2 changes: 2 additions & 0 deletions status-bar/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ ext {
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
androidxCoreVersion = project.hasProperty('androidxCoreVersion') ? rootProject.ext.androidxCoreVersion : '1.12.0'
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
androidxLocalBroadcastManagerVersion = project.hasProperty('androidxLocalBroadcastManagerVersion') ? rootProject.ext.androidxLocalBroadcastManagerVersion : '1.1.0'
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
}
Expand Down Expand Up @@ -75,6 +76,7 @@ dependencies {

implementation "androidx.core:core:$androidxCoreVersion"
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation "androidx.localbroadcastmanager:localbroadcastmanager:$androidxLocalBroadcastManagerVersion"
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.capacitorjs.plugins.statusbar;

import android.content.Intent;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
Expand All @@ -9,18 +11,26 @@
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

public class StatusBar {

private int currentStatusBarColor;
private final AppCompatActivity activity;
private final String defaultStyle;

public StatusBar(AppCompatActivity activity) {
public static final String statusBarVisibilityChanged = "statusBarVisibilityChanged";
public static final String statusBarOverlayChanged = "statusBarOverlayChanged";

public StatusBar(AppCompatActivity activity, StatusBarConfig config) {
// save initial color of the status bar
this.activity = activity;
this.currentStatusBarColor = activity.getWindow().getStatusBarColor();
this.defaultStyle = getStyle();

setBackgroundColor(config.getBackgroundColor());
setStyle(config.getStyle());
setOverlaysWebView(config.isOverlaysWebView());
}

public void setStyle(String style) {
Expand Down Expand Up @@ -49,12 +59,20 @@ public void hide() {
View decorView = activity.getWindow().getDecorView();
WindowInsetsControllerCompat windowInsetsControllerCompat = WindowCompat.getInsetsController(activity.getWindow(), decorView);
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.statusBars());
sendBroadcast(statusBarVisibilityChanged);
}

public void show() {
View decorView = activity.getWindow().getDecorView();
WindowInsetsControllerCompat windowInsetsControllerCompat = WindowCompat.getInsetsController(activity.getWindow(), decorView);
windowInsetsControllerCompat.show(WindowInsetsCompat.Type.statusBars());
sendBroadcast(statusBarVisibilityChanged);
}

private void sendBroadcast(String action) {
Intent intent = new Intent(action);
intent.putExtra("info", getInfo());
LocalBroadcastManager.getInstance(activity).sendBroadcast(intent);
}

@SuppressWarnings("deprecation")
Expand All @@ -74,6 +92,7 @@ public void setOverlaysWebView(Boolean overlays) {
// recover the previous color of the status bar
activity.getWindow().setStatusBarColor(currentStatusBarColor);
}
sendBroadcast(statusBarOverlayChanged);
}

@SuppressWarnings("deprecation")
Expand All @@ -93,6 +112,7 @@ public StatusBarInfo getInfo() {
info.setOverlays(getIsOverlaid());
info.setVisible(isVisible);
info.setColor(String.format("#%06X", (0xFFFFFF & window.getStatusBarColor())));
info.setHeight(getStatusBarHeight());
return info;
}

Expand All @@ -105,4 +125,17 @@ private String getStyle() {
}
return style;
}

private int getStatusBarHeight() {
int statusbarHeight = 0;
int resourceId = activity.getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusbarHeight = (int) activity.getApplicationContext().getResources().getDimension(resourceId);
}

DisplayMetrics metrics = activity.getApplicationContext().getResources().getDisplayMetrics();
float densityDpi = metrics.density;

return (int) (statusbarHeight / densityDpi);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.capacitorjs.plugins.statusbar;

import com.getcapacitor.util.WebColor;

public class StatusBarConfig {

private boolean overlaysWebView = true;
private Integer backgroundColor = WebColor.parseColor("#000000");
private String style = "DEFAULT";

public boolean isOverlaysWebView() {
return overlaysWebView;
}

public void setOverlaysWebView(boolean overlaysWebView) {
this.overlaysWebView = overlaysWebView;
}

public Integer getBackgroundColor() {
return backgroundColor;
}

public void setBackgroundColor(Integer backgroundColor) {
this.backgroundColor = backgroundColor;
}

public String getStyle() {
return style;
}

public void setStyle(String style) {
this.style = style;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.capacitorjs.plugins.statusbar;

public class StatusBarInfo {
import java.io.Serializable;

public class StatusBarInfo implements Serializable {

private boolean overlays;
private boolean visible;
private String style;
private String color;
private int height;

public boolean isOverlays() {
return overlays;
Expand Down Expand Up @@ -38,4 +41,12 @@ public String getColor() {
public void setColor(String color) {
this.color = color;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.capacitorjs.plugins.statusbar;

import com.getcapacitor.JSObject;
import com.getcapacitor.Logger;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
Expand All @@ -15,7 +16,35 @@ public class StatusBarPlugin extends Plugin {

@Override
public void load() {
implementation = new StatusBar(getActivity());
StatusBarConfig config = getStatusBarConfig();
implementation = new StatusBar(getActivity(), config);
}

private StatusBarConfig getStatusBarConfig() {
StatusBarConfig config = new StatusBarConfig();
String backgroundColor = getConfig().getString("StatusBarBackgroundColor");
if (backgroundColor != null) {
try {
config.setBackgroundColor(WebColor.parseColor(backgroundColor));
} catch (IllegalArgumentException ex) {
Logger.debug("Background color not applied");
}
}
config.setStyle(styleFromConfig(getConfig().getString("StatusBarStyle", config.getStyle())));
config.setOverlaysWebView(getConfig().getBoolean("StatusBarOverlaysWebView", config.isOverlaysWebView()));
return config;
}

private String styleFromConfig(String style) {
switch (style.toLowerCase()) {
case "lightcontent":
return "DARK";
case "darkcontent":
return "LIGHT";
case "default":
default:
return "DEFAULT";
}
}

@PluginMethod
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Capacitor

extension CAPBridgeViewController {

open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
NotificationCenter.default.post(Notification(name: .capacitorViewDidAppear))
}

open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
NotificationCenter.default.post(Notification(name: .capacitorViewWillTransition))
}
}
6 changes: 6 additions & 0 deletions status-bar/ios/Sources/StatusBarPlugin/CAPNotifications.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Capacitor

extension Notification.Name {
public static let capacitorViewDidAppear = Notification.Name(rawValue: "CapacitorViewDidAppear")
public static let capacitorViewWillTransition = Notification.Name(rawValue: "CapacitorViewWillTransition")
}
Loading

0 comments on commit f6d9794

Please sign in to comment.