mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-27 20:46:32 +02:00
Hides bottom navigation when keyboard is visible
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.navigation
|
package com.vitorpamplona.amethyst.ui.navigation
|
||||||
|
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.view.ViewTreeObserver
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.ime
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
@@ -15,18 +21,23 @@ import androidx.compose.material.Icon
|
|||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -44,50 +55,84 @@ val bottomNavigationItems = listOf(
|
|||||||
Route.Notification
|
Route.Notification
|
||||||
)
|
)
|
||||||
|
|
||||||
|
enum class Keyboard {
|
||||||
|
Opened, Closed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun keyboardAsState(): State<Keyboard> {
|
||||||
|
val keyboardState = remember { mutableStateOf(Keyboard.Closed) }
|
||||||
|
val view = LocalView.current
|
||||||
|
DisposableEffect(view) {
|
||||||
|
val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
|
val rect = Rect()
|
||||||
|
view.getWindowVisibleDisplayFrame(rect)
|
||||||
|
val screenHeight = view.rootView.height
|
||||||
|
val keypadHeight = screenHeight - rect.bottom
|
||||||
|
keyboardState.value = if (keypadHeight > screenHeight * 0.15) {
|
||||||
|
Keyboard.Opened
|
||||||
|
} else {
|
||||||
|
Keyboard.Closed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyboardState
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppBottomBar(navController: NavHostController, accountViewModel: AccountViewModel) {
|
fun AppBottomBar(navController: NavHostController, accountViewModel: AccountViewModel) {
|
||||||
val currentRoute = currentRoute(navController)
|
val currentRoute = currentRoute(navController)
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
Column() {
|
val isKeyboardOpen by keyboardAsState()
|
||||||
Divider(
|
|
||||||
thickness = 0.25.dp
|
|
||||||
)
|
|
||||||
BottomNavigation(
|
|
||||||
modifier = Modifier,
|
|
||||||
elevation = 0.dp,
|
|
||||||
backgroundColor = MaterialTheme.colors.background
|
|
||||||
) {
|
|
||||||
bottomNavigationItems.forEach { item ->
|
|
||||||
BottomNavigationItem(
|
|
||||||
icon = { NotifiableIcon(item, currentRoute, accountViewModel) },
|
|
||||||
selected = currentRoute == item.route,
|
|
||||||
onClick = {
|
|
||||||
coroutineScope.launch {
|
|
||||||
if (currentRoute != item.route) {
|
|
||||||
navController.navigate(item.route){
|
|
||||||
navController.graph.startDestinationRoute?.let { start ->
|
|
||||||
popUpTo(start)
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
launchSingleTop = true
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: Make it scrool to the top
|
|
||||||
navController.navigate(item.route){
|
|
||||||
navController.graph.startDestinationRoute?.let { start ->
|
|
||||||
popUpTo(start) { inclusive = item.route == Route.Home.route }
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
|
|
||||||
launchSingleTop = true
|
if (isKeyboardOpen == Keyboard.Closed) {
|
||||||
restoreState = true
|
Column() {
|
||||||
|
Divider(
|
||||||
|
thickness = 0.25.dp
|
||||||
|
)
|
||||||
|
BottomNavigation(
|
||||||
|
modifier = Modifier,
|
||||||
|
elevation = 0.dp,
|
||||||
|
backgroundColor = MaterialTheme.colors.background
|
||||||
|
) {
|
||||||
|
bottomNavigationItems.forEach { item ->
|
||||||
|
BottomNavigationItem(
|
||||||
|
icon = { NotifiableIcon(item, currentRoute, accountViewModel) },
|
||||||
|
selected = currentRoute == item.route,
|
||||||
|
onClick = {
|
||||||
|
coroutineScope.launch {
|
||||||
|
if (currentRoute != item.route) {
|
||||||
|
navController.navigate(item.route){
|
||||||
|
navController.graph.startDestinationRoute?.let { start ->
|
||||||
|
popUpTo(start)
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
launchSingleTop = true
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: Make it scrool to the top
|
||||||
|
navController.navigate(item.route){
|
||||||
|
navController.graph.startDestinationRoute?.let { start ->
|
||||||
|
popUpTo(start) { inclusive = item.route == Route.Home.route }
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
|
||||||
|
launchSingleTop = true
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user