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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:20:21