如何在Jetpack Compose中通过Retrofit实现列表/网格/RecyclerView功能
Jetpack Compose 实现同等功能方案
1. 依赖配置
你已有的Retrofit、协程相关依赖可以直接保留,仅需要在模块级build.gradle中添加Compose基础配置:
android { compileSdk 33 defaultConfig { targetSdk 33 } buildFeatures { compose true // 原有ViewBinding配置可以保留,Compose不需要但不影响原有代码运行 viewBinding true } composeOptions { // 版本与你项目使用的Kotlin版本匹配即可 kotlinCompilerExtensionVersion "1.4.3" } } dependencies { // Compose 核心依赖 implementation "androidx.compose.ui:ui:1.4.3" implementation "androidx.compose.material:material:1.4.3" implementation "androidx.activity:activity-compose:1.7.2" implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1" // 原有依赖无需修改 implementation "com.squareup.retrofit2:retrofit:2.9.0" // ... 其他原有Gson、协程、图片加载等依赖 }
2. 网络层直接复用
你现有Retrofit相关代码(数据实体类、Retrofit实例初始化逻辑)可以100%直接复用,仅需要给接口方法添加suspend关键字适配协程调用:
// 原有ApiService调整示例,其他逻辑不变 interface ApiService { @GET("你的业务接口路径") suspend fun getListData(): Response<List<你的数据实体类>> }
3. 业务逻辑层封装(ViewModel)
用ViewModel存储UI状态,驱动页面渲染,替代原有在Activity/Fragment中请求更新列表的逻辑:
class ListViewModel : ViewModel() { // 定义三种UI状态 sealed class UiState { object Loading : UiState() data class Success(val data: List<你的数据实体类>) : UiState() data class Error(val msg: String) : UiState() } val uiState = MutableStateFlow<UiState>(UiState.Loading) fun fetchData() { viewModelScope.launch { uiState.value = UiState.Loading try { val response = RetrofitInstance.api.getListData() if (response.isSuccessful && response.body() != null) { uiState.value = UiState.Success(response.body()!!) } else { uiState.value = UiState.Error("请求失败:${response.code()}") } } catch (e: Exception) { uiState.value = UiState.Error("网络错误:${e.message}") } } } }
4. UI层实现
Compose不需要编写XML布局,也不需要View Binding绑定控件,直接通过内置懒加载组件即可实现列表、网格布局,不需要单独编写Adapter、ViewHolder等模板代码。
4.1 普通列表展示(对应原ListView/列表样式RecyclerView)
使用LazyColumn组件实现:
class ComposeListActivity : ComponentActivity() { private val viewModel by viewModels<ListViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme { val state by viewModel.uiState.collectAsStateWithLifecycle() when (state) { is UiState.Loading -> { // 加载中UI Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator() } } is UiState.Error -> { // 错误提示UI Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text(text = (state as UiState.Error).msg) } } is UiState.Success -> { val list = (state as UiState.Success).data LazyColumn(modifier = Modifier.fillMaxSize()) { items(list) { item -> // 单个item布局逻辑 Row( modifier = Modifier .fillMaxWidth() .padding(16.dp) // 点击交互直接添加修饰符即可 .clickable { Toast.makeText(this@ComposeListActivity, item.title, Toast.LENGTH_SHORT).show() } ) { Image(painter = painterResource(id = R.drawable.ic_placeholder), contentDescription = null) Text(text = item.title, modifier = Modifier.padding(start = 12.dp)) } } } } } } } // 页面创建时触发数据请求 viewModel.fetchData() } }
4.2 网格布局展示(对应原GridView/网格样式RecyclerView)
仅需要把LazyColumn替换为LazyVerticalGrid即可,指定列数:
// 仅需修改成功状态下的布局代码 LazyVerticalGrid( columns = GridCells.Fixed(2), // 2列网格,可自行调整列数 modifier = Modifier.fillMaxSize() ) { items(list) { item -> // 网格item布局逻辑 Column( modifier = Modifier .padding(8.dp) .clickable { /* 处理点击逻辑 */ } ) { Image( painter = painterResource(id = R.drawable.ic_placeholder), contentDescription = null, modifier = Modifier.fillMaxWidth().aspectRatio(1f) ) Text(text = item.title, modifier = Modifier.padding(top = 8.dp)) } } }
核心差异说明
和原有View体系实现相比,Compose实现大幅减少了模板代码:
- 无需编写XML布局文件,无需View Binding绑定控件
- 无需编写Adapter、ViewHolder、布局管理器等列表相关模板代码
- 状态自动驱动UI更新,不需要手动调用
notifyDataSetChanged刷新列表 - 列表和网格布局切换仅需修改少量代码,适配不同场景成本极低
内容的提问来源于stack exchange,提问作者Ramanjeet
相关产品推荐
相关产品推荐

