Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why page transitions are so slow with NavController

I am new to using Jetpack Compose. I want to switch between pages with NavController, but strangely the fps feels very low and slow when making this transition. I have not added any animation, default animation is available. I tried to remove this default animation but I was not successful.

What could be the cause of this? What am I doing wrong?

A video showing my problem: https://www.youtube.com/shorts/Cj1vDcmhRYc

Note: I have tried on several devices and the problem is the same.

My versions about it;

implementation 'androidx.activity:activity-compose:1.8.2'
implementation "androidx.navigation:navigation-compose:2.7.6"
implementation "androidx.compose.material:material:1.5.4"
implementation 'androidx.compose.material3:material3'
implementation 'androidx.core:core-ktx:1.12.0'
implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')

My MainActivity:


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            CarCareTrackerTheme {
                val navController = rememberNavController()

                MyBottomNavigation(navController)
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyBottomNavigation(navController: NavController) {
    Scaffold(
        modifier = Modifier,
        floatingActionButton = {
            Box() {
                FloatingActionButton(
                    onClick = { /* stub */},
                    containerColor = MainBlue,
                    shape = CircleShape,
                    modifier =
                        Modifier.align(Alignment.Center)
                            .size(80.dp)
                            .offset(y = 50.dp)
                            .shadow(
                                elevation = 10.dp,
                                shape = CircleShape,
                            ),
                ) {
                    Icon(Icons.Filled.Add, contentDescription = "Add", tint = Color.White)
                }
            }
        },
        floatingActionButtonPosition = FabPosition.Center,
        content = { innerPadding ->
            NavHost(
                navController as NavHostController,
                startDestination = "home",
                Modifier.padding(innerPadding),
            ) {
                composable("home") { HomeScreen(navController) }
                composable("settings") { SettingsScreen(navController) }
            }
        },
        bottomBar = {
            BottomNavigation(backgroundColor = Color.White, contentColor = MainBlue) {
                val navBackStackEntry by navController.currentBackStackEntryAsState()
                val currentDestination = navBackStackEntry?.destination

                BottomNavigationItem(
                    icon = {
                        val isSelected =
                            currentDestination?.hierarchy?.any { it.route == "home" } == true
                        Icon(
                            Icons.Filled.Home,
                            contentDescription = null,
                            tint = if (isSelected) MainBlue else LightGray
                        )
                    },
                    label = {
                        val isSelected =
                            currentDestination?.hierarchy?.any { it.route == "home" } == true
                        Text(
                            stringResource(R.string.home),
                            color = if (isSelected) MainBlue else LightGray
                        )
                    },
                    selected = currentDestination?.hierarchy?.any { it.route == "home" } == true,
                    selectedContentColor = MainBlue,
                    onClick = {
                        navController.navigate("home") {
                            popUpTo(navController.graph.findStartDestination().id) {
                                saveState = true
                            }
                            launchSingleTop = true
                            restoreState = true
                        }
                    }
                )

                BottomNavigationItem(
                    icon = {
                        val isSelected =
                            currentDestination?.hierarchy?.any { it.route == "settings" } == true
                        Icon(
                            Icons.Filled.Settings,
                            contentDescription = null,
                            tint = if (isSelected) MainBlue else LightGray
                        )
                    },
                    label = {
                        val isSelected =
                            currentDestination?.hierarchy?.any { it.route == "settings" } == true
                        Text(
                            stringResource(R.string.settings),
                            color = if (isSelected) MainBlue else LightGray
                        )
                    },
                    selected =
                        currentDestination?.hierarchy?.any { it.route == "settings" } == true,
                    selectedContentColor = MainBlue,
                    unselectedContentColor = LightGray,
                    onClick = {
                        navController.navigate("settings") {
                            popUpTo(navController.graph.findStartDestination().id) {
                                saveState = true
                            }
                            launchSingleTop = true
                            restoreState = true
                        }
                    }
                )
            }
        }
    )
}

SettingsScreen:

@Composable
fun SettingsScreen (
    navController: NavController
){
    Column() {
        Text(text = "SettingsScreen")
        Text(text = "SettingsScreen")
    }
}

HomeScreen:

@Composable
fun HomeScreen(
    navController: NavController
) {
    Column() {
        Text(text = "HomeScreen")
        Text(text = "HomeScreen")
    }
}
like image 947
Ozgur Baykal Avatar asked Oct 26 '25 14:10

Ozgur Baykal


2 Answers

That is not actually an FPS drop; it's a default fade animation. Starting from version 2.7.0, Google transitioned Accompanist Navigation Animation back into Navigation Compose, bringing the animation features included in Accompanist with it.

You mentioned that you tried to disable this default animation but didn't explain what you have attempted. To achieve this, the navigation library now provides the ability to disable the default fade transitions using EnterTransition.None and ExitTransition.None.

NavHost(navController = rememberNavigationBarController,
        startDestination = "home",
        modifier = Modifier.padding(it),
        enterTransition = {
            // you can change whatever you want transition
            EnterTransition.None 
        },
        exitTransition = {
            // you can change whatever you want transition
            ExitTransition.None
        }
like image 68
Dilshad Avatar answered Oct 29 '25 05:10

Dilshad


I thought that the reason why it looked like there was an FPS Drop was the animation and I tried to turn off the animations. However, although I turned off the enterTransition and exitTransition animations, the Zoom animation was still visible.

According to the comments in another question on StackOverFlow; From version 2.7.0 of Navigation, even if you try to turn off the animations, the Zoom animation still remained. So I changed my version from 2.7.6 to 2.6.0.

Now you can switch without animations and there is no bad fps drop appearance (I know there is no FPS drop, but the animations make it feel like it).

SOLUTION: Use version 2.6.0 of Navigation Compose.

Differences between version 2.7.6 and 2.6.0 (VIDEOS):

WITH version 2.7.6 of Navigation Compose(Even if I turn off animations)

When I use Version 2.6.0

Resources:

Comment from midFang on StackOverFlow

issuetracker

like image 27
Ozgur Baykal Avatar answered Oct 29 '25 04:10

Ozgur Baykal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!