capacitor
capacitor copied to clipboard
bug: Navigation bar overlaps app screen
Bug Report
Capacitor Version
Latest Dependencies:
@capacitor/cli: 4.6.1
@capacitor/core: 4.5.0
@capacitor/android: 4.6.2
@capacitor/ios: 4.4.0
Installed Dependencies:
@capacitor/cli: 4.7.0
@capacitor/core: 4.7.0
@capacitor/android: 4.7.0
@capacitor/ios: 4.7.0
[success] Android looking great! 👌
[error] Xcode is not installed
Platform(s)
Android 13
Current Behavior
Navigation bar overlaps app screen
Expected Behavior
Not overlapping it
Code Reproduction
The error only happen in production, here for a working example
Code Reproduction : https://github.com/rbalet/ionic-navigation-bar-overlaps
see the add - Code reproduction
branch to see which code have been added
Other Technical Details
npm --version
output: 9.6.2
node --version
output: 18.15.0
Additional Context
- It does not happen all the time
- I didn't had this error before updating to Android 13, so seems to be related to this version
-
StatusBar.setOverlaysWebView({ overlay: false })
seems to fix this problem - The following also seems to help (Will update if I get any news)
private _setStatusBar() {
if (Capacitor.getPlatform() === 'android') {
setTimeout(() => {
StatusBar.setOverlaysWebView({ overlay: true })
StatusBar.setBackgroundColor({ color: '#00000000' })
}, 100)
}
}
Can you give this a title?
+1 facing the issue with Android 13 devices.
any updates on this bug?
Bug starting from Android API level 33
cuz currently i wrote plugin android-safe-area
and in my app code
async checkInsets() {
try {
const { top, bottom } = await SafeArea.getInsets();
document.documentElement.style.setProperty('--ion-safe-area-top', top + 'px');
document.documentElement.style.setProperty('--ion-safe-area-bottom', bottom + 'px');
} catch (e) {
console.error(e);
}
}
.keyboard-is-open {
height: calc(100% - var(--keyboard-offset, 250px) - var(--ion-safe-area-bottom, 22px));
}
Now it freaky working, but we need to be it fixed in core. Thanks in advance.
I also have this issue on Android 13 but using cordova
I also have this issue on Android 13 but using cordova
Same here
seems to be kind of a race condition too. i had an app bootstrapping and while initally mounting the first view, i set the OverlaysWebview to true. this dindt work reliably, when switching to do it in a setTimeou(... , 0) wrapper it started working as expected again. I did not investigate any further yet as this was a rather urgend hotfix.
Please, do just upvote the main issue instead of writing "non helpful text" so that the ionic team can better see if this have to be prioritised
Thx a lot <3
I've encountered the problem and solved the issue; My expected setup is
- statusBar transparent
- statusBar dark content (light mode)
- webView renders behind statusBar
- navBar transparent
- navBar dark content (light mode)
- webView renders behind navBar (we failed to achieve this and gave up in Capacitor 4)
What happened was
- on Capacitor 4, I couldn't get webView to render behind navBar, regardless of android version.
- After our team bumped up to Capacitor 5, on android 13 specifically, we faced an issue in which the setup code had no effect on plugin load time (current issue's problem). android 12 and behaved the same.
- When we changed the entire setup code's to execute 200ms(arbitrarily chosen) after webView load, the setup had full effect! (current issue's solution, thanks to @de-robat )
- Interestingly, the previous issue of not being able to get webView render behind navBar was solved in Capacitor 5 + android 13. The issue persists in android 12 & below, even with Capacitor 5.
Following snippet is my android setup function and is almost same with the ones in @capacitor/status-bar
private void setStatusBarAndNavBar() {
var activity = this.bridge.getActivity();
Window window = activity.getWindow();
View decorView = window.getDecorView();
WindowInsetsControllerCompat windowInsetsControllerCompat = WindowCompat.getInsetsController(window, decorView);
// 1. statusBar content color dark (light mode)
windowInsetsControllerCompat.setAppearanceLightStatusBars(true);
// 2. navBar content color dark (light mode)
windowInsetsControllerCompat.setAppearanceLightNavigationBars(true);
// 3. statusBar background color transparent
window.setStatusBarColor(Color.TRANSPARENT);
// 4. navBar background color transparent
window.setNavigationBarColor(Color.TRANSPARENT);
// 5. set render behind statusBar / navBar
// This had no effect on navBar on <android 12 and below + Capacitor 4>, but
// webview successfully rendered behind on navBar on <android 13 + Capacitor 5>
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
int uiOptions = decorView.getSystemUiVisibility();
uiOptions = uiOptions | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
I created a plugin for android fullscreen mode: https://github.com/digaus/community-capacitor-fullscreen
Just install and add this somewhere:
Fullscreen.addListener('insetsChanged', (insets: { top: number, bottom: number, left: number, right: number }) => {
const style = document.documentElement.style;
style.setProperty('--ion-safe-area-top', `${insets.top}px`);
style.setProperty('--ion-safe-area-bottom', `${insets.bottom}px`);
style.setProperty('--ion-safe-area-left', `${insets.left}px`);
style.setProperty('--ion-safe-area-right', `${insets.right}px`);
window.dispatchEvent(new Event('resize'));
}).catch(() => null);
StatusBar.setOverlaysWebView({ overlay: true });
I created a plugin for android fullscreen mode: https://github.com/digaus/community-capacitor-fullscreen
Just install and add this somewhere:
Fullscreen.addListener('insetsChanged', (insets: { top: number, bottom: number, left: number, right: number }) => { const style = document.documentElement.style; style.setProperty('--ion-safe-area-top', `${insets.top}px`); style.setProperty('--ion-safe-area-bottom', `${insets.bottom}px`); style.setProperty('--ion-safe-area-left', `${insets.left}px`); style.setProperty('--ion-safe-area-right', `${insets.right}px`); window.dispatchEvent(new Event('resize')); }).catch(() => null); StatusBar.setOverlaysWebView({ overlay: true });
@digaus So it actually will make the app render behind the status and navigation bars and you also get safe-area-insets for android devices ? Do you also had issues that on android the safe area insets didn’t work ? Did you also resolved that in your plugin ?
I created a plugin for android fullscreen mode: https://github.com/digaus/community-capacitor-fullscreen Just install and add this somewhere:
Fullscreen.addListener('insetsChanged', (insets: { top: number, bottom: number, left: number, right: number }) => { const style = document.documentElement.style; style.setProperty('--ion-safe-area-top', `${insets.top}px`); style.setProperty('--ion-safe-area-bottom', `${insets.bottom}px`); style.setProperty('--ion-safe-area-left', `${insets.left}px`); style.setProperty('--ion-safe-area-right', `${insets.right}px`); window.dispatchEvent(new Event('resize')); }).catch(() => null); StatusBar.setOverlaysWebView({ overlay: true });
@digaus So it actually will make the app render behind the status and navigation bars and you also get safe-area-insets for android devices ? Do you also had issues that on android the safe area insets didn’t work ? Did you also resolved that in your plugin ?
Yes, that's what the 'insetsChanged' is for.
Also takes care of rotation and inset changes.
Furthermore I added functions to change the color of the Statusbar and Navigationbar Icons/Buttons
I am having the exact same issue, for capacitor 4 it was great, i just updated to 5 and have this issue. When i put app to the background and then back in foreground it fixes itself.
I actually also have that problem with capacitor 4. Whenever the app launches I have this problem. When a request for persmissions appears, or i put the app in the backround and then again in the foreground, the problem is fixed temporarely until i completely close the app.
same :-( capacitator 5 and android 13
Adding a small delay between hiding splash screen and modifying the status bar will resolve this issue.
await SplashScreen.hide();
await new Promise(resolve => setTimeout(resolve, 500))
await StatusBar.setStyle({ style: Style.Light });
await StatusBar.setBackgroundColor({ color: '#FFFFFFF' });
Full example here: https://gist.github.com/enesien/5e64d0f29235ece5ecefad025110caf7
I also have this issue on Android 13 but using cordova
Have you found any solutions to the problem. I am using cordova android platform 12.0.1. I tried making the StatusBar.overlaysWebView(false) while the device is ready. then set a timeout and changed to StatusBar.overlaysWebView(true). But still doesn't solve the issue.
- Delete this code block if you have it: getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- Use this: if (this.platformService.isAndroid()) { StatusBar.setOverlaysWebView({overlay: true}) }
And u need write it in style.xml, it is mandatory here to assign a color to android:statusBarColor:
These steps work for me and solved this bug, now the status bar is transparent and works as it should.
It is photo: https://github.com/ionic-team/capacitor/assets/64776696/8eb3a7e3-19b5-426d-b275-270b7d247544
This is what I did to fix the issue
In onCreate
in MainActivity.java
// Set app to fullscreen and the top status bar to transparent so the webview can render underneath it
// Taken from https://github.com/ionic-team/capacitor-plugins/blob/33bdae1d3e73ac0bc63894d1cf714c57915b0605/status-bar/android/src/main/java/com/capacitorjs/plugins/statusbar/StatusBar.java#L61
View rootView = findViewById(android.R.id.content);
int uiOptions = rootView.getSystemUiVisibility();
uiOptions = uiOptions | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
rootView.setSystemUiVisibility(uiOptions);
this.getWindow().setStatusBarColor(Color.TRANSPARENT);
// Set margin so that the bottom system navigation bar doesn't clip into the webview in fullscreen mode
// Taken from https://developer.android.com/develop/ui/views/layout/edge-to-edge#system-bars-insets
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, windowInsets) -> {
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
mlp.bottomMargin = insets.bottom;
v.setLayoutParams(mlp);
return WindowInsetsCompat.CONSUMED;
});
Then I removed the call to StatusBar.setOverlaysWebView
in my frontend code. Now the navigation bar doesn't clip over the webview anymore.