1

Hey I am using BackHandler from this stackoverflow. When I am pressing back button it's not working. Can someone guide me on this.

ResultScreen.kt

@Composable
fun ResultScreen(navController: NavHostController, nearestResultList: List<NearestResult>?) {
    SportsResultTheme {
        MainScaffold {
            BackHandler {
                navController.popBackStack()
            }
            LazyColumn {
                if (nearestResultList != null) {
                    items(nearestResultList) { nearestResult ->
                        Text(
                            text = nearestResult.event
                        )
                    }
                }
            }
        }
    }
}

NavigationGraph.kt

@Composable
internal fun NavigationGraph() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = ScreenRoute.Home.route) {
        composable(ScreenRoute.Home.route) {
            SetupMainActivityView { nearestResult ->
                val nearestResultJson = Uri.encode(Json.encodeToString(nearestResult))
                navController.navigate(ScreenRoute.Result.route + "/$nearestResultJson")
            }
        }

        composable(
            ScreenRoute.Result.route + "/{$NEAREST_RESULT_JSON}",
            arguments = listOf(
                navArgument(NEAREST_RESULT_JSON) { type = NearestResultParamType() }
            )
        ) { backStackEntry ->
            ResultScreen(navController, backStackEntry.arguments?.getParcelableArrayList(NEAREST_RESULT_JSON))
        }
    }
}

If you want to see more please visit my repository.

UPDATE

You can see my video link. Anyone know when I back press why my scren flicks ?

UPDATE 2

I added splash screen in my navigation

@Composable
internal fun NavigationGraph() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = ScreenRoute.Splash.route) {

        composable(route = ScreenRoute.Splash.route) {
            SplashScreen(navController = navController)
        }

        composable(ScreenRoute.Home.route) {
            SetupMainActivityView { nearestResult ->
                val nearestResultJson = Uri.encode(Json.encodeToString(nearestResult))
                navController.navigate(ScreenRoute.Result.route + "/$nearestResultJson") {
                    popUpTo(navController.graph.findStartDestination().id) {
                        saveState = true
                    }
                    launchSingleTop = true
                    restoreState = true
                }
            }
        }

        composable(
            ScreenRoute.Result.route + "/{$NEAREST_RESULT_JSON}",
            arguments = listOf(
                navArgument(NEAREST_RESULT_JSON) { type = NearestResultParamType() }
            )
        ) { backStackEntry ->
            ResultScreen(navController, backStackEntry.arguments?.getParcelableArrayList(NEAREST_RESULT_JSON))
        }
    }
}

UPDATE 3

navController.navigate(ScreenRoute.Result.route + "/$nearestResultJson") {
                    popUpTo(ScreenRoute.Home.route) {
                        saveState = true
                    }
                    launchSingleTop = true
                    restoreState = true
                }

Back is not working when I added splash screen

UPDATE 4

@Composable
internal fun NavigationGraph() {
    val navController = rememberNavController()
    var home by remember {
        mutableStateOf<String?>(null)
    }
    NavHost(navController = navController, startDestination = home ?: ScreenRoute.Splash.route) {

        composable(route = ScreenRoute.Splash.route) {
            home = ScreenRoute.Home.route
            SplashScreen(navController = navController)
        }

        composable(ScreenRoute.Home.route) {
            SetupMainActivityView { nearestResult ->
                val nearestResultJson = Uri.encode(Json.encodeToString(nearestResult))
                navController.navigate(ScreenRoute.Result.route + "/$nearestResultJson") {
                    popUpTo(navController.graph.findStartDestination().id) {
                        saveState = true
                    }
                    launchSingleTop = true
                    restoreState = true
                }
            }
        }

        composable(
            ScreenRoute.Result.route + "/{$NEAREST_RESULT_JSON}",
            arguments = listOf(
                navArgument(NEAREST_RESULT_JSON) { type = NearestResultParamType() }
            )
        ) { backStackEntry ->
            ResultScreen(navController, backStackEntry.arguments?.getParcelableArrayList(NEAREST_RESULT_JSON))
        }
    }
}

My splash screen not working when initial application load. It direct open my home screen after going to result screen back button again not working.

Kotlin Learner
  • 3,995
  • 6
  • 47
  • 127
  • Is the backstack empty in this scenario? If it is, then `popBackStack()` only checks `if(backQueue.isEmpty())` and retuns `false`. – Ma3x Jul 21 '22 at 21:42
  • How should I know backQueue? – Kotlin Learner Jul 21 '22 at 21:43
  • No I am asking, did you navigate already inside your app and then back is not working, or is it not working on the first destination? Because in the beginning the backstack will be empty so `popBackStack()` cannot navigate back. In that case it is working as intended. – Ma3x Jul 21 '22 at 21:44
  • yes I navigate already inside is not working. – Kotlin Learner Jul 21 '22 at 21:47
  • First destination is working correctly, If I press back it close the application. But inside the the app is not working. – Kotlin Learner Jul 21 '22 at 21:48
  • Could it be that your `SetupMainActivityView` screen immediately navigates forward again after the backstack has been popped? check if [this line](https://github.com/vivek-modi/SportsResult/blob/master/app/src/main/java/com/vivek/sportsresult/ui/screen/MainActivity.kt#L95) is executed again after you press the back button – Adrian K Jul 22 '22 at 09:49
  • @AdrianK yes when I debug the line is executed again. so what the solution for this? – Kotlin Learner Jul 22 '22 at 09:55
  • do your homework before asking lot of questions in a single thread – ino Sep 13 '22 at 07:04

1 Answers1

2

try navController.navigateUp() probably the stack has many entries, try using singleton navigation to that stack is not full of undesired entries like

navController.navigate("destination") {
                    popUpTo(navController.graph.findStartDestination().id) {
                        saveState = true
                    }
                    launchSingleTop = true
                    restoreState = true
                }

try to use dynamic start destination like

var home by remember {
        mutableStateOf<String?>(null)
    }
NavHost(
        navController = navController,
        startDestination = home?:"splash_destination",
        modifier = modifier
    ) {
composable("splash) {
            home = "home_destination"
          ....
        }
.....
}

then go with previous approach

masokaya
  • 589
  • 4
  • 10
  • nothing working.. – Kotlin Learner Jul 22 '22 at 09:48
  • probably the stack has many entries, try using singleton navigation to that stack is not full of undesired entries like navController.navigate("destination") { popUpTo(navController.graph.findStartDestination().id) { saveState = true } launchSingleTop = true restoreState = true } – masokaya Jul 22 '22 at 10:49
  • 1
    can you explain me what is doing? – Kotlin Learner Jul 22 '22 at 11:08
  • it's working fine. I want to learn whats is `saveState`, `launchSingleTop` , `restoreState` is doing? – Kotlin Learner Jul 22 '22 at 11:10
  • saveState, save the ui state of the current screen, when navigating to other screen, such as rememberScrollState(), launchSingleTop for making sure only one copy of this destination is available on backstack, restoreState for restoring the stored ui state – masokaya Jul 22 '22 at 11:26
  • One another question – Kotlin Learner Jul 22 '22 at 11:27
  • I added my splash screen, so my home screen is second so how can i replace `navController.graph.findStartDestination().id` because after adding splash screen when I press back it showing me splash screen then home screen. – Kotlin Learner Jul 22 '22 at 11:28
  • Can you please guide me on this I tried `navController.graph[ScreenRoute.Home.route].id` is not working.. – Kotlin Learner Jul 22 '22 at 11:30
  • try then popUpTo("destination") { saveState = true } where destination is the route to screen you want to navigate to after backpress – masokaya Jul 22 '22 at 11:33
  • `navController.navigate(ScreenRoute.Result.route + "/$nearestResultJson") { popUpTo(ScreenRoute.Home.route) { saveState = true } launchSingleTop = true restoreState = true }` – Kotlin Learner Jul 22 '22 at 11:36
  • I tried this but not working – Kotlin Learner Jul 22 '22 at 11:36
  • please see UPDATE 2 and UPDATE 3 section – Kotlin Learner Jul 22 '22 at 11:39
  • try edited one which has dynamic start destination – masokaya Jul 22 '22 at 12:04
  • no it's not working.. – Kotlin Learner Jul 22 '22 at 12:32
  • Sorry but it's not working please have a look on UPDATE 4 section. – Kotlin Learner Jul 22 '22 at 12:34
  • try to learn from navigation codelab probably you may get more concepts on how navigation compose works https://developer.android.com/codelabs/jetpack-compose-navigation?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fcompose%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fjetpack-compose-navigation – masokaya Jul 23 '22 at 17:32
  • @vivekmodi do your homework before asking lot of questions in a single thread – ino Sep 13 '22 at 07:04