Android: handle status bar, navigation bar and keyboard insets natively and consume them, so the keyboard no longer shrinks the view twice and content no longer sits under the status bar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 00:12:21 +02:00
co-authored by Claude Opus 5.5
parent aeb6c590db
commit b431428260
3 changed files with 23 additions and 9 deletions
@@ -15,7 +15,7 @@
android:label="@string/title_activity_main" android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch" android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask" android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustNothing"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
@@ -1,10 +1,13 @@
package de.mrterm.app; package de.mrterm.app;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.WindowManager;
import android.webkit.WebView; import android.webkit.WebView;
import androidx.activity.OnBackPressedCallback; import androidx.activity.OnBackPressedCallback;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
@@ -25,14 +28,24 @@ public class MainActivity extends BridgeActivity {
} }
}); });
// Edge-to-Edge: Bei offener Tastatur den WebView um die Tastaturhöhe verkleinern, // Edge-to-Edge: Abstände für Statusleiste, Navigationsleiste und Tastatur setzt allein diese Ansicht.
// damit Terminal und Zusatztasten sichtbar bleiben // Die Insets werden danach verbraucht, damit WebView/System nicht ein zweites Mal verkleinern.
View parent = (View) web.getParent(); View parent = (View) web.getParent();
parent.setBackgroundColor(0xFF14161D);
final boolean[] imeOpen = { false };
// Vor Android 11 kommen Tastatur-Insets nicht zuverlässig: dort verkleinert das System das Fenster
final boolean legacyIme = Build.VERSION.SDK_INT < Build.VERSION_CODES.R;
if (legacyIme) getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
ViewCompat.setOnApplyWindowInsetsListener(parent, (v, insets) -> { ViewCompat.setOnApplyWindowInsetsListener(parent, (v, insets) -> {
int ime = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
v.setPadding(0, 0, 0, ime); int ime = legacyIme ? 0 : insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
web.evaluateJavascript("window.mrtermIme && window.mrtermIme(" + (ime > 0) + ")", null); v.setPadding(bars.left, bars.top, bars.right, Math.max(ime, bars.bottom));
return insets; boolean open = ime > 0;
if (open != imeOpen[0]) {
imeOpen[0] = open;
web.evaluateJavascript("window.mrtermIme && window.mrtermIme(" + open + ")", null);
}
return WindowInsetsCompat.CONSUMED;
}); });
} }
} }
+3 -2
View File
@@ -13,8 +13,9 @@
--orange: #ffb347; --orange: #ffb347;
--radius: 14px; --radius: 14px;
/* Capacitor setzt --safe-area-inset-* bei Edge-to-Edge; env() als Rückfall */ /* Capacitor setzt --safe-area-inset-* bei Edge-to-Edge; env() als Rückfall */
--top: max(env(safe-area-inset-top, 0px), var(--safe-area-inset-top, 0px)); /* Status-/Navigationsleiste und Tastatur rechnet MainActivity als Rand um den WebView heraus */
--bottom: max(env(safe-area-inset-bottom, 0px), var(--safe-area-inset-bottom, 0px)); --top: 0px;
--bottom: 0px;
color-scheme: dark; color-scheme: dark;
} }
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }