Trust zero bottom inset when gesture navigation is detected on API <= 29.

This commit is contained in:
Alex Hart
2026-04-17 12:34:06 -03:00
committed by jeffrey-signal
parent 90207b7dd7
commit 5643ffc1a9
3 changed files with 23 additions and 3 deletions

View File

@@ -152,7 +152,7 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
val isLtr = ViewUtil.isLtr(this)
val statusBar = windowInsets.top
val navigationBar = navigationBarInsetOverride ?: if (windowInsets.bottom == 0 && Build.VERSION.SDK_INT <= 29) {
val navigationBar = navigationBarInsetOverride ?: if (windowInsets.bottom == 0 && Build.VERSION.SDK_INT <= 29 && !ViewUtil.isGestureNavigation(resources, insets)) {
ViewUtil.getNavigationBarHeight(resources)
} else {
windowInsets.bottom

View File

@@ -15,10 +15,11 @@ object SystemWindowInsetsSetter {
*/
fun attach(view: View, lifecycleOwner: LifecycleOwner, @WindowInsetsCompat.Type.InsetsType insetType: Int = WindowInsetsCompat.Type.systemBars()) {
val listener = view.doOnEachLayout {
val insets: Insets? = ViewCompat.getRootWindowInsets(view)?.getInsets(insetType)
val rootInsets = ViewCompat.getRootWindowInsets(view)
val insets: Insets? = rootInsets?.getInsets(insetType)
val canTrustInsets = Build.VERSION.SDK_INT > 29 || (WindowInsetsCompat.Type.ime() and insetType == 0)
if (canTrustInsets && insets != null && !insets.isEmpty()) {
if (canTrustInsets && insets != null && (!insets.isEmpty() || ViewUtil.isGestureNavigation(view.resources, rootInsets))) {
view.post {
view.setPadding(
insets.left,

View File

@@ -406,6 +406,25 @@ public final class ViewUtil {
return result;
}
/**
* Heuristic for whether the device is currently using gesture navigation, used to decide
* when a zero bottom inset on API <= 29 should be trusted instead of replaced with the
* (3-button) navigation_bar_height fallback. Returns true if either signal reports gestures.
*/
public static boolean isGestureNavigation(@NonNull Resources resources, @Nullable WindowInsetsCompat rootInsets) {
if (rootInsets != null && rootInsets.getInsets(WindowInsetsCompat.Type.systemGestures()).bottom > 0) {
return true;
}
int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
if (resourceId > 0) {
try {
return resources.getInteger(resourceId) == 2;
} catch (Resources.NotFoundException ignored) {
}
}
return false;
}
public static void hideKeyboard(@NonNull Context context, @NonNull View view) {
InputMethodManager inputManager = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);