Jetpack Compose:通过按钮关闭应用程序

时间:2021-05-05 12:27:52

标签: kotlin android-jetpack-compose android-jetpack-navigation

NavController 无法以编程方式弹出堆栈中最新的 @Composable。 IE。如果它是根页面,则 popBackStack() 不起作用。所以应用程序可以通过点击“关闭”按钮视图关闭,只有硬件返回键允许离开应用程序。

示例:活动

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

主页.kt

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

问题:

如果使用 Compose Navigation,如何在 onClick 处理程序中关闭应用程序。

2 个答案:

答案 0 :(得分:0)

你可以使用这个:

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

答案 1 :(得分:0)

我不确定它是否必须是默认行为,因为导航组件与系统隔离并且对容器一无所知。您必须检查导航堆栈是否为空。

您需要通过 LocalBackPressedDispatcher 来撰写:

val LocalBackPressedDispatcher =
    staticCompositionLocalOf<OnBackPressedDispatcher> { error("No Back Dispatcher provided") }

class MainActivity : ComponentActivity() {
    override fun onCreate(state: Bundle?) {
        super.onCreate(state)
        setContent {
            CompositionLocalProvider(
                LocalBackPressedDispatcher provides onBackPressedDispatcher,
            ) {
                val controller = rememberNavController()
                NavHost(controller, startDestination = "HOME") {
                    composable("HOME") { HomePage(controller) }
                }
            }
        }
    }
}

然后您可以在顶部屏幕中像这样使用它:

@Composable
fun HomePage(navController: NavController) {
    val backDispatcher = LocalBackPressedDispatcher.current
    Button(onClick = backDispatcher::onBackPressed) {
        Text("Exit")
    }
}

或者如果您想要更通用的解决方案:

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

@SuppressLint("ComposableNaming")
@Composable
fun NavController.popBackStackOrBackPressAction(): () -> Unit {
    val backDispatcher = LocalBackPressedDispatcher.current
    return {
        if (previousBackStackEntry == null) {
            backDispatcher.onBackPressed()
        } else {
            popBackStack()
        }
    }
}

popBackStackOrBackPressAction 必须是可组合的,所以我们不需要每次都打开 val backDispatcher = LocalBackPressedDispatcher.current

相关问题