Jetpack Compose报错:@Composable调用需在@Composable函数上下文
解决Composable函数调用错误:"@Composable invocations can only happen from the context of a @Composable function"
你遇到的错误核心原因是:onClick是普通的点击回调,不属于@Composable上下文,不能直接在里面调用WebPageScreen这类带@Composable注解的函数——Composable函数仅允许在其他Composable函数的上下文里执行。
以下是两种可行的解决方案:
方案1:用状态控制内容切换
在MainContent中添加状态变量,通过状态切换来控制显示图片还是WebView页面:
@Composable fun MainContent() { val context = LocalContext.current // 状态变量:控制是否显示WebView var showWebView by remember { mutableStateOf(false) } Column( modifier = Modifier .fillMaxSize() .background(Color(0xFFFEFEFA)) .padding(16.dp), verticalArrangement = Arrangement.spacedBy(32.dp), horizontalAlignment = Alignment.CenterHorizontally ) { if (!showWebView) { Image( painter = painterResource(id = R.drawable.link), contentDescription = "点击加载网页", contentScale = ContentScale.Crop, modifier = Modifier .fillMaxWidth() .height(150.dp) .clickable( enabled = true, onClickLabel = "点击加载网页", onClick = { // 更新状态,触发重组显示WebView showWebView = true } ) ) } else { // 在Composable上下文中合法调用WebPageScreen WebPageScreen("https://www.google.co.in/") } } }
方案2:使用Jetpack Navigation导航(适合多页面场景)
如果你的应用包含多个页面,推荐用Jetpack Navigation组件实现页面跳转:
// 定义页面路由 sealed class Screen(val route: String) { object Home : Screen("home") object WebView : Screen("webview/{url}") { // 封装路由参数编码,避免特殊字符问题 fun createRoute(url: String) = "webview/${url.encodeURIComponent()}" } } @Composable fun AppNavHost() { val navController = rememberNavController() NavHost(navController = navController, startDestination = Screen.Home.route) { composable(Screen.Home.route) { MainContent(navController = navController) } composable(Screen.WebView.route) { backStackEntry -> // 解析路由参数 val url = backStackEntry.arguments?.getString("url")?.decodeURIComponent() ?: "" WebPageScreen(urlToRender = url) } } } // 修改MainContent,接收导航控制器 @Composable fun MainContent(navController: NavController) { val context = LocalContext.current Column( modifier = Modifier .fillMaxSize() .background(Color(0xFFFEFEFA)) .padding(16.dp), verticalArrangement = Arrangement.spacedBy(32.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Image( painter = painterResource(id = R.drawable.link), contentDescription = "点击加载网页", contentScale = ContentScale.Crop, modifier = Modifier .fillMaxWidth() .height(150.dp) .clickable( enabled = true, onClickLabel = "点击加载网页", onClick = { // 导航到WebView页面 navController.navigate(Screen.WebView.createRoute("https://www.google.co.in/")) } ) ) } }
内容的提问来源于stack exchange,提问作者user20108370
相关产品推荐
相关产品推荐

