Skip to content

Commit 7859c97

Browse files
committed
feat!: force custom statusbarView for all SDKs
1 parent 9c7ee1f commit 7859c97

File tree

2 files changed

+58
-76
lines changed

2 files changed

+58
-76
lines changed

framework/src/org/apache/cordova/CordovaActivity.java

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Licensed to the Apache Software Foundation (ASF) under one
4646
import androidx.core.graphics.Insets;
4747
import androidx.core.splashscreen.SplashScreen;
4848
import androidx.core.view.ViewCompat;
49+
import androidx.core.view.WindowCompat;
4950
import androidx.core.view.WindowInsetsCompat;
5051

5152
/**
@@ -104,6 +105,9 @@ public class CordovaActivity extends AppCompatActivity {
104105

105106
private SplashScreen splashScreen;
106107

108+
private boolean canEdgeToEdge = false;
109+
private boolean isFullScreen = false;
110+
107111
/**
108112
* Called when the activity is first created.
109113
*/
@@ -115,6 +119,9 @@ public void onCreate(Bundle savedInstanceState) {
115119
// need to activate preferences before super.onCreate to avoid "requestFeature() must be called before adding content" exception
116120
loadConfig();
117121

122+
canEdgeToEdge = preferences.getBoolean("AndroidEdgeToEdge", false)
123+
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM;
124+
118125
String logLevel = preferences.getString("loglevel", "ERROR");
119126
LOG.setLogLevel(logLevel);
120127

@@ -129,7 +136,10 @@ public void onCreate(Bundle savedInstanceState) {
129136
LOG.d(TAG, "The SetFullscreen configuration is deprecated in favor of Fullscreen, and will be removed in a future version.");
130137
preferences.set("Fullscreen", true);
131138
}
132-
if (preferences.getBoolean("Fullscreen", false)) {
139+
140+
isFullScreen = preferences.getBoolean("Fullscreen", false);
141+
142+
if (isFullScreen) {
133143
// NOTE: use the FullscreenNotImmersive configuration key to set the activity in a REAL full screen
134144
// (as was the case in previous cordova versions)
135145
if (!preferences.getBoolean("FullscreenNotImmersive", false)) {
@@ -184,6 +194,8 @@ protected void loadConfig() {
184194
//Suppressing warnings in AndroidStudio
185195
@SuppressWarnings({"deprecation", "ResourceType"})
186196
protected void createViews() {
197+
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
198+
187199
// Root FrameLayout
188200
FrameLayout rootLayout = new FrameLayout(this);
189201
rootLayout.setLayoutParams(new FrameLayout.LayoutParams(
@@ -198,47 +210,39 @@ protected void createViews() {
198210
ViewGroup.LayoutParams.MATCH_PARENT
199211
));
200212

201-
// Enable/Disable AndroidEdgeToEdge (Supported in SDK >= 35)
202-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
203-
&& !preferences.getBoolean("AndroidEdgeToEdge", false)
204-
) {
205-
// Create StatusBar view that will overlay the top inset
206-
View statusBarView = new View(this);
207-
statusBarView.setTag("statusBarView");
208-
209-
// Add statusBarView to root layout.
210-
rootLayout.addView(statusBarView);
211-
212-
// Handle Window Insets
213-
ViewCompat.setOnApplyWindowInsetsListener(rootLayout, (v, insets) -> {
214-
Insets bars = insets.getInsets(
215-
WindowInsetsCompat.Type.systemBars()
216-
| WindowInsetsCompat.Type.displayCutout()
217-
);
218-
219-
boolean isStatusBarVisible = statusBarView.getVisibility() != View.GONE;
220-
int top = isStatusBarVisible ? bars.top : 0;
221-
222-
// Update the WebView's Margin LayoutParams
223-
FrameLayout.LayoutParams newParams = (FrameLayout.LayoutParams) webView.getLayoutParams();
224-
newParams.setMargins(bars.left, top, bars.right, bars.bottom);
225-
webView.setLayoutParams(newParams);
226-
227-
// Position the status bar view to overlay the top inset areas
228-
statusBarView.setLayoutParams(new FrameLayout.LayoutParams(
229-
ViewGroup.LayoutParams.MATCH_PARENT,
230-
top,
231-
Gravity.TOP
232-
));
233-
234-
return WindowInsetsCompat.CONSUMED;
235-
});
213+
// Create StatusBar view that will overlay the top inset
214+
View statusBarView = new View(this);
215+
statusBarView.setTag("statusBarView");
236216

237-
ViewCompat.requestApplyInsets(rootLayout);
238-
}
217+
// Handle Window Insets
218+
ViewCompat.setOnApplyWindowInsetsListener(rootLayout, (v, insets) -> {
219+
Insets bars = insets.getInsets(
220+
WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()
221+
);
222+
223+
boolean isStatusBarVisible = statusBarView.getVisibility() != View.GONE;
224+
int top = isStatusBarVisible && !canEdgeToEdge && !isFullScreen ? bars.top : 0;
225+
int bottom = !canEdgeToEdge && !isFullScreen ? bars.bottom : 0;
226+
227+
FrameLayout.LayoutParams webViewParams = (FrameLayout.LayoutParams) webView.getLayoutParams();
228+
webViewParams.setMargins(bars.left, top, bars.right, bottom);
229+
webView.setLayoutParams(webViewParams);
230+
231+
FrameLayout.LayoutParams statusBarParams = new FrameLayout.LayoutParams(
232+
ViewGroup.LayoutParams.MATCH_PARENT,
233+
top,
234+
Gravity.TOP
235+
);
236+
statusBarView.setLayoutParams(statusBarParams);
237+
238+
return WindowInsetsCompat.CONSUMED;
239+
});
239240

240241
rootLayout.addView(webView);
242+
rootLayout.addView(statusBarView);
243+
241244
setContentView(rootLayout);
245+
rootLayout.post(() -> ViewCompat.requestApplyInsets(rootLayout));
242246
webView.requestFocusFromTouch();
243247
}
244248

framework/src/org/apache/cordova/SystemBarPlugin.java

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Licensed to the Apache Software Foundation (ASF) under one
2929
import android.view.ViewParent;
3030
import android.view.Window;
3131
import android.view.WindowInsetsController;
32-
import android.view.WindowManager;
3332
import android.widget.FrameLayout;
3433

3534
import androidx.core.content.ContextCompat;
@@ -50,11 +49,14 @@ public class SystemBarPlugin extends CordovaPlugin {
5049
private Resources resources;
5150
private int overrideStatusBarBackgroundColor = INVALID_COLOR;
5251

52+
private boolean canEdgeToEdge = false;
5353

5454
@Override
5555
protected void pluginInitialize() {
5656
context = cordova.getContext();
5757
resources = context.getResources();
58+
canEdgeToEdge = preferences.getBoolean("AndroidEdgeToEdge", false)
59+
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM;
5860
}
5961

6062
@Override
@@ -79,10 +81,7 @@ public Object onMessage(String id, Object data) {
7981

8082
@Override
8183
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
82-
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
83-
&& preferences.getBoolean("AndroidEdgeToEdge", false)
84-
) {
85-
// Disable JS API in E2E mode (SDK >= 35)
84+
if(canEdgeToEdge) {
8685
return false;
8786
}
8887

@@ -101,28 +100,14 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
101100
}
102101

103102
private void setStatusBarVisible(final boolean visible) {
104-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
105-
View statusBar = getStatusBarView(webView);
106-
if (statusBar != null) {
107-
statusBar.setVisibility(visible ? View.VISIBLE : View.GONE);
108-
109-
FrameLayout rootLayout = getRootLayout(webView);
110-
if (rootLayout != null) {
111-
ViewCompat.requestApplyInsets(rootLayout);
112-
}
113-
}
114-
} else {
115-
Window window = cordova.getActivity().getWindow();
116-
int uiOptions = window.getDecorView().getSystemUiVisibility();
117-
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN;
118-
if (visible) {
119-
uiOptions &= ~flags;
120-
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
121-
} else {
122-
uiOptions |= flags;
123-
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
103+
View statusBar = getStatusBarView(webView);
104+
if (statusBar != null) {
105+
statusBar.setVisibility(visible ? View.VISIBLE : View.GONE);
106+
107+
FrameLayout rootLayout = getRootLayout(webView);
108+
if (rootLayout != null) {
109+
ViewCompat.requestApplyInsets(rootLayout);
124110
}
125-
window.getDecorView().setSystemUiVisibility(uiOptions);
126111
}
127112
}
128113

@@ -138,7 +123,7 @@ private void updateSystemBars() {
138123
// Update Root View Background Color
139124
int rootViewBackgroundColor = getPreferenceBackgroundColor();
140125
if (rootViewBackgroundColor == INVALID_COLOR) {
141-
rootViewBackgroundColor = getUiModeColor();
126+
rootViewBackgroundColor = canEdgeToEdge ? Color.TRANSPARENT : getUiModeColor();
142127
}
143128
updateRootView(rootViewBackgroundColor);
144129

@@ -151,7 +136,7 @@ private void updateSystemBars() {
151136
} else if(preferences.contains("BackgroundColor")){
152137
statusBarBackgroundColor = rootViewBackgroundColor;
153138
} else {
154-
statusBarBackgroundColor = getUiModeColor();
139+
statusBarBackgroundColor = canEdgeToEdge ? Color.TRANSPARENT : getUiModeColor();
155140
}
156141

157142
updateStatusBar(statusBarBackgroundColor);
@@ -192,22 +177,15 @@ private void updateRootView(int bgColor) {
192177
private void updateStatusBar(int bgColor) {
193178
Window window = cordova.getActivity().getWindow();
194179

195-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
196-
&& !preferences.getBoolean("AndroidEdgeToEdge", false)
197-
) {
198-
View statusBar = getStatusBarView(webView);
199-
if (statusBar != null) {
200-
statusBar.setBackgroundColor(bgColor);
201-
}
180+
View statusBar = getStatusBarView(webView);
181+
if (statusBar != null) {
182+
statusBar.setBackgroundColor(bgColor);
202183
}
203184

204185
// Automatically set the font and icon color of the system bars based on background color.
205186
boolean isStatusBarBackgroundColorLight = isColorLight(bgColor);
206187
WindowInsetsControllerCompat controllerCompat = WindowCompat.getInsetsController(window, window.getDecorView());
207188
controllerCompat.setAppearanceLightStatusBars(isStatusBarBackgroundColorLight);
208-
209-
// Allow custom background color for StatusBar.
210-
window.setStatusBarColor(bgColor);
211189
}
212190

213191
private static boolean isColorLight(int color) {

0 commit comments

Comments
 (0)