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

Kotlin中RecyclerView onBindViewHolder仅调用一次问题求助

RecyclerView仅显示单个列表项的问题排查与修复

问题核心

你的getItemCount()返回正确的长度5,但onBindViewHolder()仅调用一次,界面仅显示一项,核心问题出在Adapter的逻辑设计和LiveData数据监听缺失上。

具体问题点

  1. Adapter内部数据维护错误
    你在onBindViewHolder()中每次调用都执行data.add(viewModel.getAddressesList(position)),这会导致:

    • 数据集data是逐步添加而非一次性初始化,RecyclerView复用ViewHolder时会重复添加数据,造成数据混乱
    • 未同步ViewModel中addresses LiveData的更新,数据异步加载完成后,Adapter无法感知变化,不会触发重新绑定
  2. 未监听ViewModel的LiveData变化
    Fragment中仅初始化Adapter并设置给RecyclerView,但未观察viewModel.addresses这个LiveData,导致数据加载完成后,Adapter无法更新数据集并通知RecyclerView刷新。

  3. 数据绑定未立即生效
    ViewHolder的bind()方法中仅设置了address变量,但未调用executePendingBindings(),可能导致数据绑定延迟,部分UI未正确渲染。

修复方案

1. 重构Adapter逻辑

修改Adapter,让它直接持有数据集,并提供更新方法:

class AddressListAdapter : RecyclerView.Adapter<AddressListAdapter.ViewHolder>() {

    private var addresses = emptyList<Adressen>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
            ViewHolder(
                    LayoutMyDataAddressItemBinding.inflate(
                            LayoutInflater.from(parent.context), parent, false
                    )
            )

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(addresses[position])
    }

    inner class ViewHolder(private val binding: LayoutMyDataAddressItemBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(address: Adressen) {
            binding.address = address
            // 立即执行数据绑定,确保UI及时更新
            binding.executePendingBindings()
        }
    }

    override fun getItemCount(): Int = addresses.size

    // 提供更新数据集的方法
    fun submitList(newAddresses: List<Adressen>) {
        addresses = newAddresses
        notifyDataSetChanged()
    }
}

2. 在Fragment中监听LiveData并更新Adapter

addressListAdapter = AddressListAdapter()
binding?.meineDatenAddressList?.adapter = addressListAdapter

// 监听ViewModel中的地址数据变化,更新Adapter
myDataViewModel.addresses.observe(viewLifecycleOwner) { list ->
    addressListAdapter.submitList(list ?: emptyList())
}

3. 简化ViewModel的方法(可选)

可以去掉ViewModel中getAddressesListCount()和getAddressesList()方法,直接让Adapter通过LiveData获取完整数据集,避免重复创建Adressen对象:

// ViewModel中保留addresses LiveData即可,移除以下两个方法
// fun getAddressesListCount() : Int { ... }
// fun getAddressesList(index:Int) : Adressen { ... }

额外检查点

  • 确认RecyclerView的父布局如果是NestedScrollView,保持android:nestedScrollingEnabled="false"即可,无需修改高度设置
  • 检查列表项布局中的validSince变量是否正确绑定,避免因视图GONE导致的布局高度异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:48:17