【问题标题】:Jetpack Compose: close application by buttonJetpack Compose:通过按钮关闭应用程序
【发布时间】:2021-05-05 12:27:52
【问题描述】:

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 处理程序中关闭应用。

【问题讨论】:

  • 我认为您正在寻找这个:stackoverflow.com/questions/6330200/… 在 Compose 中,您必须将活动传递给将使用它的可组合项。
  • 我们不知道框架如何使用和兑现@Composable 实体。我的意思是,我们不管理它的生命周期,因此存在上下文泄漏的风险。
  • 向 Google tracker issuetracker.google.com/issues/187134652发布了一个问题/问题

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


【解决方案1】:

你可以用这个:

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

【讨论】:

  • 经过几个月的生产,我可以说这个解决方案效果很好。谢谢。
  • 在可组合内获取活动不是一个好主意。最好将事件向上流到 ViewModel,在 Activity 中订阅它,然后在那里调用 Finish
  • .. 甚至更好:调用 onClick = { onExitClick() } 作为 lambda 传递给函数 fun HomePage(onExitClick: () -> Unit) {}
  • 将本地上下文投射到 Activity 是不安全的。传递一个 lambda 以组合并触发回托管活动似乎是最好的解决方案。
  • 我同意你们的观点,通过 lambda 可能是更好的选择,当然,这个解决方案只有在你遵循单一活动模型时才有效。但这里有一个诚实的问题:你们看到本地上下文不是 Activity 的场景?
【解决方案2】:
@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")
        }
    }
}

【讨论】:

    猜你喜欢
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多