feat: Implement navigation bar visibility handling based on navigation mode
This commit is contained in:
@@ -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) }
|
||||
}
|
||||
Reference in New Issue
Block a user