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

RecyclerView仅显示首个条目问题排查求助

问题分析与解决

你的问题核心在于Adapter的数据结构设计错误,导致RecyclerView认为只有1个列表项,所以position永远是0。具体问题和修复步骤如下:


1. 核心问题拆解

  • 你的CocktailsAdapter现在把CocktailsByBaseDto作为列表项,但实际上CocktailsByBaseDto是API返回的包装类,真正的鸡尾酒数据在它的drinks列表里。
  • getItemCount()返回的是differ.currentList.size,而你大概率只把1个CocktailsByBaseDto对象放进了differ.currentList,所以RecyclerView只会渲染1个条目,position自然永远是0。
  • 同时onBindViewHolder里用cocktail.drinks[position]是双重错误:position是Adapter的条目位置,但你的differ.currentList只有1个元素,position只能是0,这里的索引逻辑完全混乱。

2. 修复步骤

步骤1:调整Adapter的数据类型

把Adapter的泛型从CocktailsByBaseDto改成单个鸡尾酒对象(即API返回的drinks数组里的元素,假设类名叫DrinkDto)。

步骤2:修改DiffUtil回调

重新实现DiffUtil.ItemCallback来比较单个鸡尾酒对象:

private val differCallback = object : DiffUtil.ItemCallback<DrinkDto>() {
    override fun areItemsTheSame(oldItem: DrinkDto, newItem: DrinkDto): Boolean {
        return oldItem.idDrink == newItem.idDrink
    }

    override fun areContentsTheSame(oldItem: DrinkDto, newItem: DrinkDto): Boolean {
        return oldItem == newItem
    }
}

val differ = AsyncListDiffer(this, differCallback)

步骤3:修正Adapter的核心方法

修改onBindViewHolder和getItemCount,直接操作单个鸡尾酒对象:

override fun onBindViewHolder(holder: CocktailsViewHolder, position: Int) {
    val binding = holder.binding
    val cocktail = differ.currentList[position]

    holder.itemView.apply {
        Glide.with(this).load(cocktail.strDrinkThumb).into(binding.imgCocktailsMainRecyclerViewImage)
        binding.tvCocktailsMainRecyclerViewTitle.text = cocktail.strDrink
        Log.e("TAG", "$position")
        setOnClickListener {
            onItemClickListener?.let { it(cocktail) }
        }
    }
}

override fun getItemCount(): Int {
    return differ.currentList.size
}

// 同时修改点击监听的类型
private var onItemClickListener: ((DrinkDto) -> Unit)? = null

fun setOnItemClickListener(listener: (DrinkDto) -> Unit) {
    onItemClickListener = listener
}

步骤4:修正数据源传递

当你从API获取到CocktailsByBaseDto后,不要把整个对象放进differ.currentList,而是把它的drinks列表传进去:

// 假设apiResponse是你获取到的CocktailsByBaseDto实例
cocktailsAdapter.differ.submitList(apiResponse.drinks)

3. 为什么之前的尝试没用?

你之前修改val cocktail = differ.currentList[position]里的position为0,本质上还是在操作只有1个元素的列表,所以RecyclerView依然只会显示1个条目,position自然不会递增。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:21:15