Sergey Krivenkov
Sergey Krivenkov

Reputation: 659

Jetpack Compose: close application by button

NavController can't pop programmatically the latest @Composable in the stack. I.e. popBackStack() doesn't work if it's a root page. So the application can be closed by tap on "Close" button view and only hardware Back key allows to leave application.

Example: Activity

class AppActivity : ComponentActivity() {
    override fun onCreate(state: Bundle?) {
        super.onCreate(state)
        setContent {
            val controller = rememberNavController()
            NavHost(controller, startDestination = HOME) {
                composable(HOME) { HomePage(controller) }
                ...
            }
        }
    }
}

HomePage.kt

@Composable
fun HomePage(controller: NavController) {
    Button(onClick = {
        controller.popBackStack()
    }) {
        Text("Exit")
    }
}

Question:

How to close the app in onClick handler if Compose Navigation is used.

Upvotes: 26

Views: 32878

Answers (4)

Jamal N
Jamal N

Reputation: 658

I did it like this by passing the finish() function from the main Activity down to my component

Activity:

NavHost(
            navController = navController,
            startDestination = AppScreens.MainMenu.name
        ) {
            composable(route = AppScreens.MainMenu.name) {
                MainMenuScreen(
                    navController = navController,
                    onExit = { finish()}
                )
            }
        }

Component:

@Composable
fun MainMenuScreen(
    navController: NavController,
    onExit: () -> Unit
) { 
...
Button(
         modifier = Modifier,
         onClick = {onExit()}
      )

Upvotes: 1

wbk727
wbk727

Reputation: 8408

finishAffinity() closes your app and keeps it in the Recent apps screen

finishAndRemoveTask() closes your app and removes it from the Recent apps screen

Upvotes: 2

WAMii
WAMii

Reputation: 51

@AndroidEntryPoint
class MainActivity:AppCompatActivity() {

  @ExperimentalAnimatedInsets
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    WindowCompat.setDecorFitsSystemWindows(window, false)
    val activityKiller: () -> Unit = {
      this.finish()
    }

    setContent {
      MainAppEntry(activityKiller = activityKiller)
    }
  }
}

@Composable
fun MainAppEntry(activityKiller: () -> Unit) {
  val mainViewModel: MainViewModel = hiltViewModel<MainViewModel>()
  //mutableStateOf .......
  var isKillRequested = mainViewModel.mainActivityState.isActivityFinishRequested
  if (isKillRequested) {
    activityKiller()
    return
  }

  Column(Modifier.fillMaxSize()) {
    TextButton(onClick = {
      mainViewModel.smuaActivityState.requestActivityFinish()
    }) {
      Text(text = "Kill app")
    }
  }
}

Upvotes: 4

nglauber
nglauber

Reputation: 23964

You can use this:

@Composable
fun HomePage(controller: NavController) {
    val activity = (LocalContext.current as? Activity)
    Button(onClick = {
        activity?.finish()
    }) {
        Text("Exit")
    }
}

Upvotes: 74

Related Questions