Jetpack Compose报错:LocalContext.current需在@Composable上下文调用
问题:在Composable按钮的onClick回调中获取LocalContext触发错误
开发应用Home Screen时,Sign Up按钮的onClick回调里执行val context = LocalContext.current,触发错误提示:
@Composable invocations can only happen from the context of a @Composable function
完整代码如下:
@Composable fun HomeScreen(navController: NavController) { // Use a Box to allow for layering of composables on top of each other // Used to keep the content at the bottom center of the screen. Box( modifier = Modifier .fillMaxSize() .padding(16.dp), // Apply padding around the box contentAlignment = Alignment.BottomCenter // Align content to the bottom center ) { // Column to stack buttons vertically Column( // Center column contents horizontally horizontalAlignment = Alignment.CenterHorizontally, // Space between the column contents verticalArrangement = Arrangement.spacedBy(8.dp) ) { // Button to NAVIGATE TO THE BENEFITS SCREEN Button( onClick = { navController.navigate("sleep_benefits") }, // Apply padding to only the top of the first button to push it upwards modifier = Modifier.padding(bottom = 1.dp) ) { Text(text = "Learn About Sleep Benefits") } // Button for USER LOGIN Button( onClick = { /* TODO: Add navigation to login screen here */ } ) { Text(text = "Login to Track Sleep") } // New Sign Up Button Button( onClick = { val context = LocalContext.current context.startActivity(Intent(context, SignInActivity::class.java)) }, modifier = Modifier.padding(top = 8.dp) ) { Text(text = "Sign Up") } } } }
解决方案
问题原因
LocalContext.current是Composable调用,只能在被@Composable标记的函数或lambda内部执行,而按钮的onClick回调是普通函数类型,不属于Composable上下文,直接调用会触发错误。
修复步骤
在HomeScreen这个Composable函数的顶层(或Button所在的Composable作用域内)提前获取LocalContext,再在onClick回调中使用这个变量。
修改后的代码
@Composable fun HomeScreen(navController: NavController) { // 在Composable作用域内提前获取Context val context = LocalContext.current Box( modifier = Modifier .fillMaxSize() .padding(16.dp), contentAlignment = Alignment.BottomCenter ) { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(8.dp) ) { Button( onClick = { navController.navigate("sleep_benefits") }, modifier = Modifier.padding(bottom = 1.dp) ) { Text(text = "Learn About Sleep Benefits") } Button( onClick = { /* TODO: 跳转到登录页面 */ } ) { Text(text = "Login to Track Sleep") } Button( onClick = { // 直接使用提前获取的context启动Activity context.startActivity(Intent(context, SignInActivity::class.java)) }, modifier = Modifier.padding(top = 8.dp) ) { Text(text = "Sign Up") } } } }
补充说明
所有Composable类型的调用(比如LocalContext.current、remember、自定义Composable函数等)都必须放在@Composable标记的上下文中。普通回调(如onClick、onChange)不属于这个上下文,因此需要提前在合法的Composable作用域内获取所需值,再传递给回调使用。
内容的提问来源于stack exchange,提问作者Collins Kariuki
相关产品推荐
相关产品推荐

