如何在Kotlin中正确将API响应的data数据展示到RecyclerView?
问题排查与解决方案
以下是导致RecyclerView无法正常展示数据的核心问题及对应修复方案:
1. 数据类字段与JSON结构完全不匹配
JSON返回的字段和LocData的定义存在多处不匹配,直接导致Gson解析失败:
- JSON中是
locationName,数据类误用name - JSON中
id/organizationId是数字类型,数据类定义为String? - JSON中
headOffice/deleted是布尔类型,数据类定义为String? - JSON中
state可能为null,数据类定义为非空String - 数据类多余
locationId字段(JSON中无此字段)
修复后的LocData:
data class LocData ( val id: Int?, val country: String?, val locationName: String?, val address1: String?, val headOffice: Boolean?, val address2: String?, val zipCode: String?, val city: String?, val deleted: Boolean?, val organizationName: String?, val organizationId: Int?, val state: String? )
2. API接口定义错误
原接口错误添加了@Query("locations")参数,且未匹配API返回的顶层结构(JSON包含status/data等外层字段)。
第一步:添加顶层响应数据类
data class LocationResponse( val status: Boolean, val statusCode: Int, val statusMessage: String, val errorMessage: String?, val data: List<LocData> )
第二步:修正Api接口
interface Api { @GET("locations/getAll/24") suspend fun getAllLocations(): LocationResponse }
3. Repository层逻辑补充(缺失部分)
实现正确的Retrofit调用逻辑:
class LocationRepository { private val api = Retrofit.Builder() .baseUrl(Url.url) .addConverterFactory(GsonConverterFactory.create()) .build() .create(Api::class.java) suspend fun getLocations(): LocationResponse { return api.getAllLocations() } }
4. ViewModel层修正
正确提取JSON中的data字段并通过LiveData发送:
class LocationViewModel(private val repository: LocationRepository) : ViewModel() { private val _myResponse = MutableLiveData<List<LocData>>() val myResponse: LiveData<List<LocData>> = _myResponse fun getPost() { viewModelScope.launch { try { val response = repository.getLocations() _myResponse.postValue(response.data) } catch (e: Exception) { e.printStackTrace() // 可替换为错误处理逻辑 } } } }
5. Adapter与MainActivity修正
适配器空值处理(避免空指针崩溃)
override fun onBindViewHolder(holder: LocationViewHolder, position: Int) { val location = locationList[position] holder.id.text = location.id?.toString() ?: "" holder.locName.text = location.locationName ?: "" holder.address1.text = location.address1 ?: "" holder.address2.text = location.address2 ?: "" holder.city.text = location.city ?: "" holder.state.text = location.state ?: "" holder.country.text = location.country ?: "" holder.zipCode.text = location.zipCode ?: "" holder.headOffice.text = location.headOffice?.toString() ?: "" holder.deleted.text = location.deleted?.toString() ?: "" holder.orgName.text = location.organizationName ?: "" holder.orgId.text = location.organizationId?.toString() ?: "" } // 优化setLocationData方法,兼容List类型 fun setLocationData(locationList: List<LocData>) { this.locationList = ArrayList(locationList) notifyDataSetChanged() }
MainActivity观察者修正
locationViewModel.myResponse.observe(this) { locList -> postAdapter.setLocationData(locList) recyclerView.visibility = View.VISIBLE }
6. 依赖补充(确保build.gradle中包含)
// Retrofit相关 implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // ViewModel相关 implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
内容的提问来源于stack exchange,提问作者Akshay Prakash
相关产品推荐
相关产品推荐

