From e96a50b4545e452b6c4d72c17e29e260f0e57c58 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 22 May 2023 15:08:14 -0400 Subject: [PATCH] Optimizes recomposition of bottom items. --- .../amethyst/ui/navigation/AppBottomBar.kt | 84 +++++++++++-------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt index 0d715b80e..bae0bb5af 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt @@ -5,6 +5,7 @@ import android.view.ViewTreeObserver import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -36,6 +37,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavHostController +import androidx.navigation.compose.currentBackStackEntryAsState import com.vitorpamplona.amethyst.NotificationCache import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -82,11 +84,7 @@ fun keyboardAsState(): State { @Composable fun AppBottomBar(navController: NavHostController, accountViewModel: AccountViewModel) { - val currentRoute = currentRoute(navController) - val currentRouteBase = currentRoute?.substringBefore("?") - val coroutineScope = rememberCoroutineScope() val isKeyboardOpen by keyboardAsState() - if (isKeyboardOpen == Keyboard.Closed) { Column() { Divider( @@ -98,43 +96,59 @@ fun AppBottomBar(navController: NavHostController, accountViewModel: AccountView backgroundColor = MaterialTheme.colors.background ) { bottomNavigationItems.forEach { item -> - val selected = currentRouteBase == item.base - - BottomNavigationItem( - icon = { NotifiableIcon(item, selected, accountViewModel) }, - selected = selected, - onClick = { - coroutineScope.launch { - if (currentRouteBase != item.base) { - navController.navigate(item.base) { - navController.graph.startDestinationRoute?.let { start -> - popUpTo(start) - restoreState = true - } - launchSingleTop = true - restoreState = true - } - } else { - val route = currentRoute.replace("{scrollToTop}", "true") - navController.navigate(route) { - navController.graph.startDestinationRoute?.let { start -> - popUpTo(start) { inclusive = item.route == Route.Home.route } - restoreState = true - } - - launchSingleTop = true - restoreState = true - } - } - } - } - ) + BottomIcon(item, accountViewModel, navController) } } } } } +@Composable +private fun RowScope.BottomIcon( + item: Route, + accountViewModel: AccountViewModel, + navController: NavHostController +) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + + navBackStackEntry?.let { navBackStackEntry -> + val currentRoute = remember(navBackStackEntry) { navBackStackEntry.destination.route } + val currentRouteBase = remember(navBackStackEntry) { navBackStackEntry.destination.route?.substringBefore("?") } + val selected = remember(navBackStackEntry) { currentRouteBase == item.base } + val coroutineScope = rememberCoroutineScope() + + BottomNavigationItem( + icon = { NotifiableIcon(item, selected, accountViewModel) }, + selected = selected, + onClick = { + coroutineScope.launch { + if (!selected) { + navController.navigate(item.base) { + navController.graph.startDestinationRoute?.let { start -> + popUpTo(start) + restoreState = true + } + launchSingleTop = true + restoreState = true + } + } else if (currentRoute != null) { + val route = currentRoute.replace("{scrollToTop}", "true") + navController.navigate(route) { + navController.graph.startDestinationRoute?.let { start -> + popUpTo(start) { inclusive = item.route == Route.Home.route } + restoreState = true + } + + launchSingleTop = true + restoreState = true + } + } + } + } + ) + } +} + @Composable private fun NotifiableIcon(route: Route, selected: Boolean, accountViewModel: AccountViewModel) { val scope = rememberCoroutineScope()