Список в RecyclerView не обновляется при изменении списка

Почему мой список в RecyclerView не обновляется, когда я добавляю в список новый объект? Я использовал DiffUtil и поставил точку останова в реализованных методах, и я получаю обновленное значение в differ.submitList(value), но не в «diffcallback». В первом случае я создаю список, у меня нет проблем, но когда я добавляю в список еще один элемент, он не отражается. Пожалуйста, посмотрите мой адаптер RecyclerView

    class VehiclesInvolvedAdapter : RecyclerView.Adapter<VehiclesInvolvedAdapter.VehiclesInvolvedViewHolder>(){
        inner class VehiclesInvolvedViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
    
        private val diffCallback = object : DiffUtil.ItemCallback<VehicleInformation>() {
            override fun areItemsTheSame(
                oldItem: VehicleInformation,
                newItem: VehicleInformation
            ): Boolean {
                return oldItem.id == newItem.id
            }
    
            override fun areContentsTheSame(
                oldItem: VehicleInformation,
                newItem: VehicleInformation
            ): Boolean {
                return oldItem == newItem
            }
        }
    
        private val differ = AsyncListDiffer(this, diffCallback)
        var vehicleInformationList: List<VehicleInformation>
        get() = differ.currentList
        set(value) {
            differ.submitList(value)
        }
    
    
    
        override fun getItemCount() = differ.currentList.size
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VehiclesInvolvedViewHolder {
            return VehiclesInvolvedViewHolder(
                LayoutInflater.from(parent.context).inflate(
                    R.layout.item_vehicle_involved,
                    parent,
                    false
                )
            )
        }
    
        override fun onBindViewHolder(holder: VehiclesInvolvedViewHolder, position: Int) {
            val vehicleInformation = vehicleInformationList[position]
    
            holder.itemView.apply {
                var btnVehicle = findViewById<TextView>(R.id.btnVehicle)
                btnVehicle.text = vehicleInformation.plateNumber
    
                setOnClickListener {
                    onItemClickListener?.let { it(vehicleInformation) }
                }
            }
        }
    
        private var onItemClickListener: ((VehicleInformation) -> Unit)? = null
    
        fun setOnItemClickListener(listener: (VehicleInformation) -> Unit) {
            onItemClickListener = listener
        }
    }

    // This is how I add another object to the List
    private fun setupRecyclerView() = binding!!.rvVehicleInvolved.apply {
        vehicleInvolvedAdapter = VehiclesInvolvedAdapter()
        adapter = vehicleInvolvedAdapter
        layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
    }
    
    private fun addOBject() {
        vehicleInformationList.add(vehicleInformation)
        vehicleInvolvedAdapter.vehicleInformationList = vehicleInformationList => THIS IS SUPPOSED TO UPDATE THE ITEMS IN THE RECYCLERVIEW
    }
2
0
118
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы не уведомляете адаптер об изменении, внесенном в список, ознакомьтесь с различными функциями уведомления в документации (https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter) и выбрать наиболее подходящий. Я предполагаю, что новый список полностью отличается от предыдущего и предлагаю вам это изменение:

private fun addOBject() {
    vehicleInformationList.add(vehicleInformation)
    vehicleInvolvedAdapter.vehicleInformationList = vehicleInformationList
    vehicleInvolvedAdapter.notifyDataSetChanged()
}

Я рекомендую вам не использовать notifyDataSetChanged() из-за проблем с производительностью в больших списках, вместо этого используйте notifyItemRangeChanged(int positionStart, int itemCount) для обновления только тех элементов, которые были добавлены или изменены.

vehicleInvolvedAdapter необходимо уведомлять каждый раз, когда vehicleInformationList обновляется. Замените функцию addOBject на следующую:

private fun addOBject() {
    vehicleInformationList.add(vehicleInformation)
    vehicleInvolvedAdapter.vehicleInformationList = vehicleInformationList 
    vehicleInvolvedAdapter.notifyDataSetChanged()
}

Читайте по следующей ссылке: Адаптеры

  1. вы добавляете новый элемент в список
  2. вы уведомляете, что список изменился
  3. Different сравнивает «новый» список со «старым» списком
  4. это один и тот же экземпляр в обоих случаях, поэтому не может быть никаких различий -> без обновления

Вы в основном обошли различие, незаметно изменив его список.

В качестве быстрого хака вы можете использовать:

set(value) {
    differ.submitList(value.toList()) //makes a copy
}

Но вам действительно нужно переосмыслить, как работают списки. Неизменяемость — это способ предотвратить такие проблемы.

Кроме того, в опубликованном вами коде чего-то не хватает: vehicleInformationList.add это невозможно, потому что список неизменяем. Неизменяемость сохраняется с помощью vehicleInformationList = vehicleInformationList.plus(vehicleInformation)

Другие вопросы по теме