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

Jetpack Compose中API数据无法渲染Card组件问题求助

问题分析与修复方案

核心问题:StateFlow未被正确观察,UI无法感知数据变化

你当前直接访问cardViewModel.cards.value获取数据,这种方式无法让Compose感知到StateFlow的状态更新。即便API返回了正确数据,UI也不会触发重组,导致HomeScreen无法接收到新数据,Card组件自然不会渲染。

具体修复步骤

1. 正确收集StateFlow状态

移除@SuppressLint("StateFlowValueCalledInComposition")注解(这是错误用法的掩盖),改用collectAsStateWithLifecycle()观察StateFlow,确保数据变化时UI自动重组:

修改YuGiOhApp.kt

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun YuGiOhApp(cardViewModel: CardViewModel = hiltViewModel()) {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
    // 正确收集StateFlow,需依赖androidx.lifecycle:lifecycle-runtime-compose库
    val cardsState by cardViewModel.observeUIState().collectAsStateWithLifecycle()

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = { AppTopAppBar(scrollBehavior = scrollBehavior) }
    ) { paddingValues ->
        Surface(
            modifier = Modifier
                .fillMaxSize()
                .padding(paddingValues)
        ) {
            when (val cardsResponse = cardsState) {
                null -> {
                    // 加载状态
                    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                        CircularProgressIndicator()
                    }
                }
                else -> {
                    cardsResponse.data?.let { cardList ->
                        if (cardList.isEmpty()) {
                            // 空数据状态
                            Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                                Text(text = "暂无卡牌数据")
                            }
                        } else {
                            HomeScreen(cards = cardList)
                        }
                    } ?: run {
                        // 数据异常状态
                        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                            Text(text = "数据加载异常")
                        }
                    }
                }
            }
        }
    }
}

2. 修正HomeScreen的Modifier传递与Card布局

移除HomeScreen的@SuppressLint("StateFlowValueCalledInComposition"),修正LazyColumn的Modifier参数,同时给Card添加padding避免布局拥挤:

修改HomeScreen.kt

@Composable
fun HomeScreen(cards: List<Data>, modifier: Modifier = Modifier) {
    LazyColumn(modifier = modifier.fillMaxSize()) {
        Log.i("IN the column", "yayaya")
        items(cards) { card ->
            Card(modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), card = card)
            Log.i("IN THE ITEMS", "tatata")
        }
    }
}

@Composable
fun Card(modifier: Modifier, card: Data) {
    Column(modifier = modifier) {
        AsyncImage(
            model = ImageRequest.Builder(LocalContext.current)
                .data(card.cardImages.getOrNull(0)) // 用getOrNull避免索引越界崩溃
                .crossfade(true)
                .build(),
            contentDescription = stringResource(id = R.string.card),
            modifier = Modifier.fillMaxWidth(),
            // 可选:添加占位图与错误图,方便调试
            placeholder = painterResource(R.drawable.ic_placeholder),
            error = painterResource(R.drawable.ic_error)
        )
        Text(
            text = card.name ?: "未知卡牌",
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(vertical = 4.dp)
        )
    }
}

3. 优化ViewModel的API调用(可选)

将OkHttp的回调式调用改为Coroutine挂起函数方式,更符合Kotlin协程使用习惯:

修改CardViewModel.kt

private fun getCards() {
    viewModelScope.launch {
        try {
            val response = repository.getNetwork().execute()
            if (response.isSuccessful) {
                cards.value = response.body()
                Log.i("message: ", response.body().toString())
            } else {
                cards.value = null
                Log.e("API Error", "响应码: ${response.code()}")
            }
        } catch (t: Throwable) {
            cards.value = null
            Log.e("API 请求失败", t.message, t)
        }
    }
}

额外注意事项

  • 确保依赖androidx.lifecycle:lifecycle-runtime-compose库,否则collectAsStateWithLifecycle()无法使用。
  • 检查数据类Data中的cardİmages字段名是否与API返回字段匹配(注意土耳其语İ和英语i的区别,大概率是拼写错误,建议改为cardImages)。

内容的提问来源于stack exchange,提问作者Chadus Maximus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:34:56