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

Jetpack Compose中API请求响应后如何更新LazyColumn列表

问题原因及解决方案

核心问题1:网络请求被反复调用

你将searchByName("poodle")直接写在了组合函数的作用域内,Compose的重组会反复执行这块代码,导致程序陷入「发起请求→更新列表→触发重组→再发起请求」的死循环,界面一直被阻塞无法渲染。

核心问题2:Image组件未设置固定高度

你没有给Image设置明确尺寸,Coil加载图片完成前控件高度为0,就算列表重组成功也看不到内容。


修正步骤

  1. 将网络请求移到setContent外,或者用LaunchedEffect包裹保证仅执行一次
  2. 给Image添加固定高度属性
  3. 可选优化:用和Compose生命周期绑定的协程代替全局协程,避免内存泄漏

修正后的完整代码

class MainActivity : ComponentActivity() {
    private val dogImages = mutableStateListOf<String>()

    @ExperimentalCoilApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 网络请求放在onCreate里,仅执行一次
        searchByName("poodle")
        setContent {
            PuppyWallpapersTheme {
                Surface(color = MaterialTheme.colors.background) {
                    DogList(dogImages)
                }
            }
        }
    }

    private fun getRetrofit():Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://dog.ceo/api/breed/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    private fun searchByName(query: String) {
        CoroutineScope(Dispatchers.IO).launch {
            val call = getRetrofit().create(APIService::class.java).getDogsByBreed("$query/images")
            val puppies = call.body()
            runOnUiThread {
                if (call.isSuccessful) {
                    val images = puppies?.images ?: emptyList()
                    dogImages.clear()
                    dogImages.addAll(images)
                }
            }
        }
    }

    @ExperimentalCoilApi
    @Composable
    fun DogList(dogs: SnapshotStateList<String>) {
        LazyColumn {
            items(dogs) { dog ->
                DogCard(dog)
            }
        }
    }

    @ExperimentalCoilApi
    @Composable
    fun DogCard(dog: String) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(15.dp),
            elevation = 10.dp
        ) {
            Image(
                painter = rememberImagePainter(dog),
                contentDescription = null,
                // 给Image设置固定高度
                modifier = Modifier.fillMaxWidth().height(200.dp),
                contentScale = ContentScale.Crop
            )
        }
    }
}

如果要更符合Compose规范,可以用LaunchedEffect来处理网络请求,不需要把列表变量定义在Activity层面:

@ExperimentalCoilApi
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        PuppyWallpapersTheme {
            Surface(color = MaterialTheme.colors.background) {
                val dogImages = remember { mutableStateListOf<String>() }
                DogList(dogImages)
                // 仅在页面初始化时执行一次网络请求
                LaunchedEffect(Unit) {
                    val puppies = withContext(Dispatchers.IO) {
                        val call = getRetrofit().create(APIService::class.java).getDogsByBreed("poodle/images")
                        if (call.isSuccessful) call.body() else null
                    }
                    puppies?.images?.let { images ->
                        dogImages.clear()
                        dogImages.addAll(images)
                    }
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:09:03