如何通过Gson-Volley访问idClubLocal字段?已获取codCompeticion与nomCompeticion
解决Gson+Volley解析嵌套数组中idClubLocal字段的问题
嘿,看你遇到了用Gson和Volley解析数据时,外层字段能正常获取但嵌套的idClubLocal访问不了的问题,这大概率是Model类的结构没和接口返回的JSON数据完全匹配导致的,咱们一步步来搞定:
第一步:修正Model类的定义
Gson解析完全依赖Model类和JSON结构的一一对应,你需要把嵌套的jornadas数组单独抽成一个Model类,再在外层类里引用它:
// 对应jornadas数组里的单个赛程对象 data class Jornada( val idClubLocal: String, // 记得把接口返回的jornadas里其他需要的字段也加上,比如idClubVisitante、fecha等 ) // 外层的竞赛对象,对应JSON数组里的每个元素 data class Competicion( val codCompeticion: String, val nomCompeticion: String, val jornadas: List<Jornada> // 注意这里是List<Jornada>类型,对应JSON里的数组结构 )
如果你的ModelList是用来包裹整个JSON数组的,其实直接用List<Competicion>就行,不需要额外的包裹类(除非接口返回的是{"data": [数组]}这种带外层键的结构,那才需要ModelList来对应)。
第二步:调整Volley请求的解析逻辑
在FragJorActual里,确保Volley的Gson请求用对了泛型类型,这样才能正确解析嵌套数组:
// 替换成你的实际接口URL val apiUrl = "https://your-api-address.com/competiciones" // 创建GsonRequest,泛型指定为List<Competicion> val gsonRequest = object : GsonRequest<List<Competicion>>( Request.Method.GET, apiUrl, // 获取List<Competicion>的Type对象,避免Gson解析数组时出错 TypeToken.getParameterized(List::class.java, Competicion::class.java).type, Response.Listener { competiciones -> // 数据解析成功,这里就能拿到所有竞赛数据,包括嵌套的jornadas competiciones.forEach { competicion -> Log.d("解析测试", "竞赛编码: ${competicion.codCompeticion}") Log.d("解析测试", "竞赛名称: ${competicion.nomCompeticion}") // 遍历jornadas数组,就能正常访问idClubLocal了 competicion.jornadas.forEach { jornada -> Log.d("解析测试", "主场俱乐部ID: ${jornada.idClubLocal}") } } // 把数据传给Adapter val adapter = CalendarioAdapterArray(competiciones) // 假设你用RecyclerView,设置Adapter yourRecyclerView.adapter = adapter }, Response.ErrorListener { error -> Log.e("请求错误", "接口请求失败: ${error.message}") } ) // 添加到Volley请求队列 Volley.newRequestQueue(requireContext()).add(gsonRequest)
第三步:在Adapter中访问idClubLocal
在CalendarioAdapterArray里,你可以通过外层的Competicion对象拿到jornadas列表,进而访问idClubLocal,记得做判空处理避免崩溃:
class CalendarioAdapterArray(private val competiciones: List<Competicion>) : RecyclerView.Adapter<CalendarioAdapterArray.ViewHolder>() { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvCompeticionInfo: TextView = itemView.findViewById(R.id.tv_competicion_info) val tvLocalClubId: TextView = itemView.findViewById(R.id.tv_local_club_id) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val itemView = LayoutInflater.from(parent.context) .inflate(R.layout.item_competicion, parent, false) return ViewHolder(itemView) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val currentCompeticion = competiciones[position] // 显示外层字段 holder.tvCompeticionInfo.text = "${currentCompeticion.codCompeticion} - ${currentCompeticion.nomCompeticion}" // 处理嵌套的jornadas,先判空避免空指针异常 currentCompeticion.jornadas.firstOrNull()?.let { firstJornada -> holder.tvLocalClubId.text = "主场ID: ${firstJornada.idClubLocal}" } ?: run { holder.tvLocalClubId.text = "暂无赛程数据" } } override fun getItemCount() = competiciones.size }
几个容易踩的坑要注意
- 字段名完全匹配:Model类里的字段名要和JSON返回的完全一致,比如JSON里是
idClubLocal,Model里就不能写成id_club_local;如果想自定义字段名,要加@SerializedName("idClubLocal")注解,比如:data class Jornada( @SerializedName("idClubLocal") val localClubId: String ) - 数组类型匹配:
jornadas在JSON里是数组,所以Model类里必须用List<Jornada>或者Array<Jornada>,不能写成单个Jornada对象。 - 判空处理:如果接口返回的
jornadas可能是空数组,一定要用firstOrNull()、isEmpty()等方法判断,避免NullPointerException。
内容的提问来源于stack exchange,提问作者Rafel C.F
相关产品推荐
相关产品推荐

