如何解决为什么Diffutil AsyncListDiffer 的submitList 方法不刷新我的recyclerview?
我正在 recyclerview 中实现 recyclerview,如下图所示,并使用 diffutil asynclistdiffer 来管理列表元素中的更改。
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)
}}
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 举报,一经查实,本站将立刻删除。