feat: Implement navigation bar visibility handling based on navigation mode

This commit is contained in:
2026-02-09 10:34:40 +05:00
parent e1c119f621
commit 8dfcf1c410
7 changed files with 225 additions and 31 deletions

View File

@@ -0,0 +1,96 @@
package com.rosetta.messenger.ui.utils
import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
/**
* Утилита для определения типа системной навигации.
*
* Android поддерживает 3 режима:
* - 0 = 3-button navigation (нативные кнопки: Back, Home, Recents)
* - 1 = 2-button navigation (кнопка Home + жест назад)
* - 2 = Gesture navigation (полностью жестовая навигация, без кнопок)
*
* Если у устройства gesture navigation (2), нижний navigation bar прячем.
* Если у устройства кнопочная навигация (0 или 1), показываем navigation bar.
*/
object NavigationModeUtils {
private const val NAV_MODE_THREE_BUTTON = 0
private const val NAV_MODE_TWO_BUTTON = 1
private const val NAV_MODE_GESTURE = 2
/**
* Возвращает текущий режим навигации.
* 0 = 3-button, 1 = 2-button, 2 = gesture
*/
fun getNavigationMode(context: Context): Int {
return try {
val resId = context.resources.getIdentifier(
"config_navBarInteractionMode", "integer", "android"
)
if (resId > 0) context.resources.getInteger(resId) else NAV_MODE_THREE_BUTTON
} catch (_: Exception) {
NAV_MODE_THREE_BUTTON
}
}
/**
* true если устройство использует жестовую навигацию (без нативных кнопок внизу)
*/
fun isGestureNavigation(context: Context): Boolean {
return getNavigationMode(context) == NAV_MODE_GESTURE
}
/**
* true если у устройства есть нативная панель навигации (3 или 2 кнопки)
*/
fun hasNativeNavigationBar(context: Context): Boolean {
return !isGestureNavigation(context)
}
/**
* Показывает или прячет navigation bar в зависимости от типа навигации.
* - Кнопочная навигация → показываем бар
* - Жестовая навигация → прячем бар, свайп снизу временно покажет
*/
fun applyNavigationBarVisibility(
insetsController: WindowInsetsControllerCompat,
context: Context,
isDarkTheme: Boolean
) {
if (hasNativeNavigationBar(context)) {
// Есть нативные кнопки — показываем навигационный бар
insetsController.show(WindowInsetsCompat.Type.navigationBars())
insetsController.isAppearanceLightNavigationBars = !isDarkTheme
} else {
// Жестовая навигация — прячем навигационный бар
insetsController.hide(WindowInsetsCompat.Type.navigationBars())
insetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
}
/**
* Composable-хелпер: запоминает, использует ли устройство жестовую навигацию.
*/
@Composable
fun rememberIsGestureNavigation(): Boolean {
val context = LocalContext.current
return remember { NavigationModeUtils.isGestureNavigation(context) }
}
/**
* Composable-хелпер: запоминает, есть ли нативная навигационная панель.
*/
@Composable
fun rememberHasNativeNavigationBar(): Boolean {
val context = LocalContext.current
return remember { NavigationModeUtils.hasNativeNavigationBar(context) }
}