capacitor-plugin-status-bar 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -42,62 +42,65 @@ public class StatusBar extends Plugin {
|
|
|
42
42
|
private int currentStatusBarColor = Color.BLACK;
|
|
43
43
|
private int currentNavBarColor = Color.BLACK;
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
setupEdgeToEdgeBehavior();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private void setupEdgeToEdgeBehavior() {
|
|
52
|
-
Activity activity = getActivity();
|
|
53
|
-
if (activity == null)
|
|
54
|
-
return;
|
|
55
|
-
|
|
56
|
-
Window window = activity.getWindow();
|
|
57
|
-
View decorView = window.getDecorView();
|
|
58
|
-
|
|
59
|
-
WindowCompat.setDecorFitsSystemWindows(window, false);
|
|
60
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // Android 14+
|
|
61
|
-
ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, insets) -> {
|
|
62
|
-
ViewCompat.onApplyWindowInsets(v, insets);
|
|
63
|
-
return insets;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
45
|
+
// Note: load() is not called since StatusBar is instantiated via new StatusBar()
|
|
46
|
+
// from StatusBarPlugin, not registered as a Capacitor plugin itself.
|
|
47
|
+
// All initialization happens via ensureEdgeToEdgeConfigured() called from StatusBarPlugin.load().
|
|
67
48
|
|
|
68
49
|
/**
|
|
69
50
|
* Ensures edge-to-edge is properly configured for Android 15+.
|
|
70
|
-
*
|
|
71
|
-
*
|
|
51
|
+
* Sets up a unified insets listener on the decorView that handles both
|
|
52
|
+
* IME insets and overlay view sizing.
|
|
72
53
|
*
|
|
73
54
|
* @param activity The activity to configure
|
|
74
55
|
*/
|
|
75
56
|
public void ensureEdgeToEdgeConfigured(Activity activity) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
View decorView = window.getDecorView();
|
|
57
|
+
Window window = activity.getWindow();
|
|
58
|
+
View decorView = window.getDecorView();
|
|
79
59
|
|
|
80
|
-
|
|
81
|
-
|
|
60
|
+
// Enable edge-to-edge for ALL API levels.
|
|
61
|
+
// window.setStatusBarColor() is unreliable on many devices/OEMs,
|
|
62
|
+
// so we use overlay views to control bar colors consistently.
|
|
63
|
+
WindowCompat.setDecorFitsSystemWindows(window, false);
|
|
82
64
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
65
|
+
// Make native bar colors transparent so our overlays are the sole color source
|
|
66
|
+
window.setStatusBarColor(Color.TRANSPARENT);
|
|
67
|
+
window.setNavigationBarColor(Color.TRANSPARENT);
|
|
68
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
69
|
+
window.setStatusBarContrastEnforced(false);
|
|
70
|
+
window.setNavigationBarContrastEnforced(false);
|
|
71
|
+
}
|
|
86
72
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
// Single unified insets listener on decorView for overlay sizing
|
|
74
|
+
ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, insets) -> {
|
|
75
|
+
// Size status bar overlay
|
|
76
|
+
int top = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
|
|
77
|
+
View statusOverlay = ((ViewGroup) v).findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
78
|
+
if (statusOverlay != null) {
|
|
79
|
+
ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
|
|
80
|
+
if (params.height != top) {
|
|
81
|
+
params.height = top;
|
|
82
|
+
statusOverlay.setLayoutParams(params);
|
|
83
|
+
Log.d(TAG, "insetsListener: status bar overlay height=" + top);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
91
86
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
// Size navigation bar overlay
|
|
88
|
+
int bottom = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
89
|
+
View navOverlay = ((ViewGroup) v).findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
90
|
+
if (navOverlay != null) {
|
|
91
|
+
ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
|
|
92
|
+
if (params.height != bottom) {
|
|
93
|
+
params.height = bottom;
|
|
94
|
+
navOverlay.setLayoutParams(params);
|
|
95
|
+
Log.d(TAG, "insetsListener: nav bar overlay height=" + bottom);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
95
98
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
ViewCompat.onApplyWindowInsets(v, insets);
|
|
100
|
+
return insets;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
Log.d(TAG, "ensureEdgeToEdgeConfigured: edge-to-edge with overlay views, API=" + Build.VERSION.SDK_INT);
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
public void setOverlaysWebView(Activity activity, boolean overlay) {
|
|
@@ -195,11 +198,6 @@ public class StatusBar extends Plugin {
|
|
|
195
198
|
Log.d(TAG, "setStyle: style=" + style + ", colorHex=" + colorHex);
|
|
196
199
|
Window window = activity.getWindow();
|
|
197
200
|
|
|
198
|
-
// Enable drawing of system bar backgrounds (required for color changes)
|
|
199
|
-
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
|
200
|
-
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
201
|
-
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
|
|
202
|
-
|
|
203
201
|
// Store the current style and color for later reapplication
|
|
204
202
|
currentStyle = style;
|
|
205
203
|
currentColorHex = colorHex;
|
|
@@ -384,16 +382,14 @@ public class StatusBar extends Plugin {
|
|
|
384
382
|
|
|
385
383
|
private void applyStatusBarBackground(Activity activity, @ColorInt int color) {
|
|
386
384
|
Log.d(TAG, "applyStatusBarBackground: color=#" + Integer.toHexString(color) + ", API=" + Build.VERSION.SDK_INT);
|
|
387
|
-
// Use overlay
|
|
388
|
-
// (setDecorFitsSystemWindows=false) makes window.setStatusBarColor() ineffective
|
|
385
|
+
// Use overlay views for all API levels for consistent behavior
|
|
389
386
|
ensureStatusBarOverlay(activity, color);
|
|
390
387
|
}
|
|
391
388
|
|
|
392
389
|
private void applyNavigationBarBackground(Activity activity, @ColorInt int color) {
|
|
393
390
|
Log.d(TAG, "applyNavigationBarBackground: color=#" + Integer.toHexString(color) + ", API="
|
|
394
391
|
+ Build.VERSION.SDK_INT);
|
|
395
|
-
// Use overlay
|
|
396
|
-
// (setDecorFitsSystemWindows=false) makes window.setNavigationBarColor() ineffective
|
|
392
|
+
// Use overlay views for all API levels for consistent behavior
|
|
397
393
|
ensureNavBarOverlay(activity, color);
|
|
398
394
|
}
|
|
399
395
|
|
|
@@ -401,52 +397,38 @@ public class StatusBar extends Plugin {
|
|
|
401
397
|
Log.d(TAG, "ensureStatusBarOverlay: color=#" + Integer.toHexString(color));
|
|
402
398
|
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
|
403
399
|
View existing = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
400
|
+
|
|
401
|
+
// Get current status bar height synchronously for immediate sizing
|
|
402
|
+
int initialHeight = 0;
|
|
403
|
+
WindowInsetsCompat rootInsets = ViewCompat.getRootWindowInsets(decorView);
|
|
404
|
+
if (rootInsets != null) {
|
|
405
|
+
initialHeight = rootInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
|
|
406
|
+
}
|
|
407
|
+
|
|
404
408
|
if (existing == null) {
|
|
405
|
-
Log.d(TAG, "ensureStatusBarOverlay: creating new overlay");
|
|
409
|
+
Log.d(TAG, "ensureStatusBarOverlay: creating new overlay, initialHeight=" + initialHeight);
|
|
406
410
|
View overlay = new View(activity);
|
|
407
411
|
overlay.setTag(STATUS_BAR_OVERLAY_TAG);
|
|
408
412
|
overlay.setBackgroundColor(color);
|
|
409
413
|
|
|
410
414
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
|
|
411
415
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
412
|
-
|
|
413
|
-
lp.topMargin = 0;
|
|
416
|
+
initialHeight);
|
|
414
417
|
overlay.setLayoutParams(lp);
|
|
415
418
|
|
|
416
|
-
// Add to the top of the decor view
|
|
417
419
|
decorView.addView(overlay);
|
|
418
|
-
|
|
419
|
-
// Listen on decorView for reliable insets dispatch across all API levels,
|
|
420
|
-
// then use WindowInsetsCompat.Type.statusBars() for accurate status-bar-only height
|
|
421
|
-
ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, windowInsets) -> {
|
|
422
|
-
int top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
|
|
423
|
-
View statusOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
424
|
-
if (statusOverlay != null) {
|
|
425
|
-
ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
|
|
426
|
-
if (params.height != top) {
|
|
427
|
-
params.height = top;
|
|
428
|
-
statusOverlay.setLayoutParams(params);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
int bottom = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
433
|
-
View navOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
434
|
-
if (navOverlay != null) {
|
|
435
|
-
ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
|
|
436
|
-
if (params.height != bottom) {
|
|
437
|
-
params.height = bottom;
|
|
438
|
-
navOverlay.setLayoutParams(params);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
ViewCompat.onApplyWindowInsets(v, windowInsets);
|
|
443
|
-
return windowInsets;
|
|
444
|
-
});
|
|
420
|
+
// Sizing updates are handled by the unified listener in ensureEdgeToEdgeConfigured
|
|
445
421
|
decorView.requestApplyInsets();
|
|
446
422
|
} else {
|
|
447
423
|
Log.d(TAG, "ensureStatusBarOverlay: updating existing overlay");
|
|
448
424
|
existing.setBackgroundColor(color);
|
|
449
|
-
|
|
425
|
+
// Update height if it was 0 (listener hadn't fired yet)
|
|
426
|
+
ViewGroup.LayoutParams params = existing.getLayoutParams();
|
|
427
|
+
if (params.height == 0 && initialHeight > 0) {
|
|
428
|
+
params.height = initialHeight;
|
|
429
|
+
existing.setLayoutParams(params);
|
|
430
|
+
Log.d(TAG, "ensureStatusBarOverlay: fixed height to " + initialHeight);
|
|
431
|
+
}
|
|
450
432
|
}
|
|
451
433
|
}
|
|
452
434
|
|
|
@@ -464,53 +446,39 @@ public class StatusBar extends Plugin {
|
|
|
464
446
|
Log.d(TAG, "ensureNavBarOverlay: color=#" + Integer.toHexString(color));
|
|
465
447
|
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
|
466
448
|
View existing = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
449
|
+
|
|
450
|
+
// Get current nav bar height synchronously for immediate sizing
|
|
451
|
+
int initialHeight = 0;
|
|
452
|
+
WindowInsetsCompat rootInsets = ViewCompat.getRootWindowInsets(decorView);
|
|
453
|
+
if (rootInsets != null) {
|
|
454
|
+
initialHeight = rootInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
455
|
+
}
|
|
456
|
+
|
|
467
457
|
if (existing == null) {
|
|
468
|
-
Log.d(TAG, "ensureNavBarOverlay: creating new overlay");
|
|
458
|
+
Log.d(TAG, "ensureNavBarOverlay: creating new overlay, initialHeight=" + initialHeight);
|
|
469
459
|
View overlay = new View(activity);
|
|
470
460
|
overlay.setTag(NAV_BAR_OVERLAY_TAG);
|
|
471
461
|
overlay.setBackgroundColor(color);
|
|
472
462
|
|
|
473
463
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
|
|
474
464
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
475
|
-
|
|
465
|
+
initialHeight);
|
|
476
466
|
lp.gravity = Gravity.BOTTOM;
|
|
477
467
|
overlay.setLayoutParams(lp);
|
|
478
468
|
|
|
479
469
|
decorView.addView(overlay);
|
|
480
|
-
|
|
481
|
-
// Insets sizing is handled by the shared decorView listener in ensureStatusBarOverlay.
|
|
482
|
-
// If status bar overlay was not created yet, set up the listener here.
|
|
483
|
-
if (decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG) == null) {
|
|
484
|
-
ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, windowInsets) -> {
|
|
485
|
-
int top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
|
|
486
|
-
View statusOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
487
|
-
if (statusOverlay != null) {
|
|
488
|
-
ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
|
|
489
|
-
if (params.height != top) {
|
|
490
|
-
params.height = top;
|
|
491
|
-
statusOverlay.setLayoutParams(params);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
int bottom = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
496
|
-
View navOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
497
|
-
if (navOverlay != null) {
|
|
498
|
-
ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
|
|
499
|
-
if (params.height != bottom) {
|
|
500
|
-
params.height = bottom;
|
|
501
|
-
navOverlay.setLayoutParams(params);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
ViewCompat.onApplyWindowInsets(v, windowInsets);
|
|
506
|
-
return windowInsets;
|
|
507
|
-
});
|
|
508
|
-
}
|
|
470
|
+
// Sizing updates are handled by the unified listener in ensureEdgeToEdgeConfigured
|
|
509
471
|
decorView.requestApplyInsets();
|
|
510
472
|
} else {
|
|
511
473
|
Log.d(TAG, "ensureNavBarOverlay: updating existing overlay");
|
|
512
474
|
existing.setBackgroundColor(color);
|
|
513
|
-
|
|
475
|
+
// Update height if it was 0 (listener hadn't fired yet)
|
|
476
|
+
ViewGroup.LayoutParams params = existing.getLayoutParams();
|
|
477
|
+
if (params.height == 0 && initialHeight > 0) {
|
|
478
|
+
params.height = initialHeight;
|
|
479
|
+
existing.setLayoutParams(params);
|
|
480
|
+
Log.d(TAG, "ensureNavBarOverlay: fixed height to " + initialHeight);
|
|
481
|
+
}
|
|
514
482
|
}
|
|
515
483
|
}
|
|
516
484
|
|
|
@@ -536,18 +504,15 @@ public class StatusBar extends Plugin {
|
|
|
536
504
|
*/
|
|
537
505
|
private void makeStatusBarBackgroundTransparent(Activity activity) {
|
|
538
506
|
Log.d(TAG, "makeStatusBarBackgroundTransparent: API=" + Build.VERSION.SDK_INT);
|
|
539
|
-
|
|
507
|
+
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
|
540
508
|
|
|
541
|
-
// Make overlay views transparent (used for all API levels)
|
|
542
|
-
ViewGroup decorView = (ViewGroup) window.getDecorView();
|
|
543
509
|
View statusBarOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
|
|
544
|
-
View navBarOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
545
|
-
|
|
546
510
|
if (statusBarOverlay != null) {
|
|
547
511
|
statusBarOverlay.setBackgroundColor(Color.TRANSPARENT);
|
|
548
512
|
Log.d(TAG, "makeStatusBarBackgroundTransparent: status bar overlay made transparent");
|
|
549
513
|
}
|
|
550
514
|
|
|
515
|
+
View navBarOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
|
|
551
516
|
if (navBarOverlay != null) {
|
|
552
517
|
navBarOverlay.setBackgroundColor(Color.TRANSPARENT);
|
|
553
518
|
Log.d(TAG, "makeStatusBarBackgroundTransparent: navigation bar overlay made transparent");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capacitor-plugin-status-bar",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Capacitor plugin for managing the status bar style, visibility, and color on iOS and Android. Control overlay modes, background colors, and appearance for native mobile applications.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|