Почему мой список в 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
}
Вы не уведомляете адаптер об изменении, внесенном в список, ознакомьтесь с различными функциями уведомления в документации (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()
}
Читайте по следующей ссылке: Адаптеры
Вы в основном обошли различие, незаметно изменив его список.
В качестве быстрого хака вы можете использовать:
set(value) {
differ.submitList(value.toList()) //makes a copy
}
Но вам действительно нужно переосмыслить, как работают списки. Неизменяемость — это способ предотвратить такие проблемы.
Кроме того, в опубликованном вами коде чего-то не хватает: vehicleInformationList.add
это невозможно, потому что список неизменяем. Неизменяемость сохраняется с помощью vehicleInformationList = vehicleInformationList.plus(vehicleInformation)