You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:01:12