微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么Diffutil AsyncListDiffer 的submitList 方法不刷新我的recyclerview?

如何解决为什么Diffutil AsyncListDiffer 的submitList 方法不刷新我的recyclerview?

我正在 recyclerview 中实现 recyclerview,如下图所示,并使用 diffutil asynclistdiffer 来管理列表元素中的更改。

List of event cards

在下面添加片段和适配器的代码

CustomizeEventFragment 代码

class CustomizeEventFragment : Fragment(){

private lateinit var mContext: Context
private lateinit var viewmodel: CustomizeEventviewmodel
private lateinit var customizeEventRecyclerAdapter: CustomizeEventRecyclerAdapter

companion object {
    fun newInstance() = CustomizeEventFragment()
}

override fun onAttach(context: Context) {
    super.onAttach(context)
    mContext = context
}

override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.customize_event_fragment,container,false)
}

override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
    super.onViewCreated(view,savedInstanceState)
    Log.d("App","Inside onviewcreated customize event fragment")
    viewmodel = activity?.let { viewmodelProvider(it).get(CustomizeEventviewmodel::class.java) }!!
    subscibeObservers()
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    Log.d("App","Inside onactivity created of customize event fragment")

}

private fun subscibeObservers(){
    viewmodel.customizeEventList.observe(viewLifecycleOwner,Observer {
        it?.let {
            rv_customizeEvents.apply {
                layoutManager = linearlayoutmanager(mContext)
                customizeEventRecyclerAdapter = CustomizeEventRecyclerAdapter(null,viewmodel)
                adapter = customizeEventRecyclerAdapter
                setHasFixedSize(true)
            }
            customizeEventRecyclerAdapter.submitList(it)
        }
    })
}}

CustomizeEventRecyclerAdapter 代码

class CustomizeEventRecyclerAdapter(private val interaction: Interaction? = null,val viewmodel: CustomizeEventviewmodel) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

val DIFF_CALLBACK = object : DiffUtil.ItemCallback<CustomizeEventModel>() {

    override fun areItemsTheSame(oldItem: CustomizeEventModel,newItem: CustomizeEventModel): Boolean {
        return oldItem.eventModel.eventName == newItem.eventModel.eventName
    }

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

}
private val differ = AsyncListDiffer(this,DIFF_CALLBACK)

override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): RecyclerView.ViewHolder {

    return ListViewHolder(
            LayoutInflater.from(parent.context).inflate(
                    R.layout.item_customized_event,parent,false
            ),interaction
    )
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder,position: Int) {
    when (holder) {
        is ListViewHolder -> {
            Log.d("App","Inside onbindviewholder adapter")
            holder.bind(differ.currentList.get(position))
        }
    }
}

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

fun submitList(list: List<CustomizeEventModel>) {
    Log.d("App","Inside submit list" + list.toString())
    differ.submitList(list)
}

inner class ListViewHolder
constructor(
        itemView: View,private val interaction: Interaction?
) : RecyclerView.ViewHolder(itemView),SelectedItemsRecyclerAdapter.Interaction {

    fun bind(item: CustomizeEventModel) = with(itemView) {

        itemView.tv_cardEventTitle.text = item.eventModel.eventName
        if (item.eventModel.member2.equals("")){
            itemView.tv_cardMembers.text = "Members: ${item.eventModel.member1}"
        }else{
            itemView.tv_cardMembers.text = "Members: ${item.eventModel.member1},${item.eventModel.member2}"
        }

        if (item.selectedCake.itemName.equals("")){
            itemView.btn_selectCake.setText("Select Cake")
        }else{
            itemView.btn_selectCake.setText(item.selectedCake.itemName)
        }

        itemView.btn_selectCake.setonClickListener {
            val action: NavDirections = CustomizeEventFragmentDirections.actionCustomizeEventFragmentToBottomSheetCakeFragment(adapterPosition)
            Navigation.findNavController(it).navigate(action)
        }

        itemView.btn_addItem.setonClickListener {
            val action: NavDirections = CustomizeEventFragmentDirections.actionCustomizeEventFragmentToBottomSheetAddItemsFragment(adapterPosition)
            Navigation.findNavController(it).navigate(action)
        }

        if (!item.selectedweight.equals("")){
            itemView.weightSelection.setText(item.selectedweight)
        }
        val weights: ArrayList<String> = ArrayList()
        val variants = item.selectedCake.variant
        for (i in variants){
            weights.add(i.weight)
        }

        val adspinner = ArrayAdapter(context,R.layout.item_citytext,weights)
        (itemView.weightSelection as? AutoCompleteTextView)?.setAdapter(adspinner)

        itemView.weightSelection.setonItemClickListener { parent,view,position,id ->
            viewmodel.updateSelectedWeight(parent.getItemAtPosition(position).toString(),adapterPosition)
        }

        val selectedItemsRecyclerAdapter: SelectedItemsRecyclerAdapter

        rv_itemList.apply {
            layoutManager = linearlayoutmanager(context.applicationContext)
            selectedItemsRecyclerAdapter = SelectedItemsRecyclerAdapter(this@ListViewHolder)
            adapter = selectedItemsRecyclerAdapter
            setHasFixedSize(true)
        }

        if (!item.selectedItems.isNullOrEmpty()){
            selectedItemsRecyclerAdapter.submitList(item.selectedItems.toList())
        }
    }

    override fun onItemRemoved(itemPosition: Int) {
        viewmodel.removeSelectedItem(itemPosition,adapterPosition)
    }
}

interface Interaction {
    fun onItemSelected(position: Int)
}}

如所附屏幕截图所示,当单击添加项目按钮时,另一个适配器被调用以设置所选项目的列表,我们也可以在单击“X”按钮时删除这些项目。 SelectedItemsRecyclerAdapter 代码

class SelectedItemsRecyclerAdapter(private val interaction: Interaction? = null) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {

val DIFF_CALLBACK = object : DiffUtil.ItemCallback<ProductModel>() {

    override fun areItemsTheSame(oldItem: ProductModel,newItem: ProductModel): Boolean {
        return oldItem.itemName == newItem.itemName
    }

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

}
private val differ = AsyncListDiffer(this,viewType: Int): RecyclerView.ViewHolder {

    return ListViewHolder(
        LayoutInflater.from(parent.context).inflate(
            R.layout.item_selected_items,false
        ),position: Int) {
    when (holder) {
        is ListViewHolder -> {
            holder.bind(differ.currentList.get(position))
        }
    }
}

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

fun submitList(list: List<ProductModel>) {
    differ.submitList(list)
}

inner class ListViewHolder
constructor(
    itemView: View,private val interaction: Interaction?
) : RecyclerView.ViewHolder(itemView) {

    fun bind(item: ProductModel) = with(itemView) {

        itemView.tv_itemName.text = item.itemName
        itemView.iv_removeItem.setonClickListener {
            interaction?.onItemRemoved(adapterPosition)
        }
    }
}

interface Interaction {
    fun onItemRemoved(itemPosition: Int)
}}

CustomizeEventviewmodel 代码

    class CustomizeEventviewmodel(application: Application) : Androidviewmodel(application) {
   var customizeEventList = mutablelivedata<List<CustomizeEventModel>>()

    fun updateCustomizeEventList(selectedEvents: List<EventModel>){
        val _customizeEventList: MutableList<CustomizeEventModel> = mutablelistof()

        for (item in selectedEvents){
            val _customizeEventModel = CustomizeEventModel(item)
            _customizeEventList.add(_customizeEventModel)
        }

        customizeEventList.value = _customizeEventList.toList()
    }

    fun updateSelectedCake(model: ProductModel,position: Int){
        val _customizeEventList: MutableList<CustomizeEventModel>? = customizeEventList.value as MutableList<CustomizeEventModel>?

        val customizeEventModel: CustomizeEventModel = _customizeEventList?.get(position)!!
        customizeEventModel.selectedCake = model

        _customizeEventList.set(position,customizeEventModel)
        customizeEventList.value = _customizeEventList.toList()
    }

    fun updateSelectedWeight(weight: String,adPosition: Int){
        val _customizeEventList: MutableList<CustomizeEventModel>? = customizeEventList.value as MutableList<CustomizeEventModel>?

        val customizeEventModel: CustomizeEventModel = _customizeEventList?.get(adPosition)!!
        customizeEventModel.selectedweight = weight

        _customizeEventList.set(adPosition,customizeEventModel)
        customizeEventList.value = _customizeEventList.toList()
    }

    fun updateSelectedItem(item: ProductModel,position: Int){
        val _customizeEventList: MutableList<CustomizeEventModel>? = customizeEventList.value as MutableList<CustomizeEventModel>?

        val itemList: ArrayList<ProductModel> = _customizeEventList?.get(position)?.selectedItems!!
        itemList.add(item)

        val customizeEventModel: CustomizeEventModel = _customizeEventList.get(position)
        customizeEventModel.selectedItems = itemList

        _customizeEventList.set(position,customizeEventModel)
        customizeEventList.value = _customizeEventList.toList()
    }

    fun removeSelectedItem (itemPosition: Int,adPosition: Int){
        val _customizeEventList: MutableList<CustomizeEventModel>? = customizeEventList.value as MutableList<CustomizeEventModel>?

        val itemList: ArrayList<ProductModel> = _customizeEventList?.get(adPosition)?.selectedItems!!
        itemList.removeAt(itemPosition)

        val customizeEventModel: CustomizeEventModel = _customizeEventList.get(adPosition)
        customizeEventModel.selectedItems = itemList

        _customizeEventList.set(adPosition,customizeEventModel)
        customizeEventList.value = _customizeEventList.toList()

    }}

问题描述: 在 CustomizeEventFragment 中,当对任何事件卡执行 Select cake、Add items 或 Remove selected Items 的操作时,然后在观察者内部我调用 CustomizeEventAdapters submitlist 方法并每次传递更新的列表。因此,每当列表数据更改/更新时,观察者都会被调用,但这会导致整个回收站视图更新它的 UI,如 notifydatasetchanged。我认为这是因为我正在观察者内部初始化 recyclerview 和适配器。

当假设我对第三个事件卡执行任何操作时,这会导致问题,然后在观察者因该更改而受到命中后,它会导致整个 recyclerview 更新其 UI,并且 recyclerview 中的项目从第一个初始位置显示。 recyclerview 更新后,它应该停留在第 3 个事件卡位置。

我尝试在观察者之外删除以下 recyclerview 和适配器初始化代码

rv_customizeEvents.apply {
                layoutManager = linearlayoutmanager(mContext)
                customizeEventRecyclerAdapter = CustomizeEventRecyclerAdapter(null,viewmodel)
                adapter = customizeEventRecyclerAdapter
                setHasFixedSize(true)
            }

但是当我这样做时,仅在观察者内部调用customizeEventRecyclerAdapter submitlist 方法不会检测/更新recyclerview UI 以更改列表。 Diffutil asynclistdiffer submitlist 方法应该处理更改,但我无法理解为什么它没有按预期工作。 请指出我在片段/适配器代码或视图模型实现中犯的任何错误

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。