【问题标题】:IndexOutOfBoundsException ListAdapterIndexOutOfBoundsException ListAdapter
【发布时间】:2023-03-27 19:42:01
【问题描述】:

我正在从通常的 RecyclerView 迁移到 ListAdapter:

abstract class BaseAdapter<T>(
@LayoutRes
val normalLayoutId: Int,
@LayoutRes
val loadingLayoutId: Int = R.layout.progress_loading,
sm: (T, T) -> Boolean,
val itemsCells: ArrayList<T?> = ArrayList()
  ) : ListAdapter<T, RecyclerView.ViewHolder>(TaskDiffCallbac(sm)) {
val VIEW_TYPE_ITEM = 0
val VIEW_TYPE_LOADING = 1

class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

class LoadingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

fun addData(dataViews: ArrayList<T>) {
    itemsCells.addAll(dataViews)
    this.submitList(dataViews)
    notifyDataSetChanged()
}


override fun getItemViewType(position: Int): Int {
    return if (getItem(position) == null) {
        VIEW_TYPE_LOADING
    } else {
        VIEW_TYPE_ITEM
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    return if (viewType == Constant.VIEW_TYPE_ITEM) {
        val view =
            LayoutInflater.from(parent.context).inflate(normalLayoutId, parent, false)
        ItemViewHolder(view)
    } else {
        val view =
            LayoutInflater.from(parent.context).inflate(loadingLayoutId, parent, false)
        LoadingViewHolder(view)
    }
}

fun addLoadingView() {
    itemsCells.add(null)
    submitList(itemsCells)
}

fun removeLoadingView() {
    if (itemsCells.size != 0) {
        itemsCells.removeAt(itemsCells.size - 1)
       submitList(itemsCells)
    }
}

fun clearItems() {
    itemsCells.clear()
    submitList(itemsCells)
}

class TaskDiffCallbac<T>(val sm: (T, T) -> Boolean) : DiffUtil.ItemCallback<T>() {
    override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
        return sm(oldItem, newItem)
    }

    @SuppressLint("DiffUtilEquals")
    override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
        return oldItem == newItem
    }
 }

}

但是在调试时我得到了这个异常:

 java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
2021-02-19 11:38:11.770 5602-5668/? E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
Process: com.timelysoft.shelter, PID: 5602
java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
    at java.util.ArrayList.get(ArrayList.java:437)
    at androidx.recyclerview.widget.AsyncListDiffer$1$1.areItemsTheSame(AsyncListDiffer.java:306)
    at androidx.recyclerview.widget.DiffUtil.diffPartial(DiffUtil.java:268)
    at androidx.recyclerview.widget.DiffUtil.calculateDiff(DiffUtil.java:145)
    at androidx.recyclerview.widget.DiffUtil.calculateDiff(DiffUtil.java:105)
    at androidx.recyclerview.widget.AsyncListDiffer$1.run(AsyncListDiffer.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)

有什么问题?

【问题讨论】:

    标签: android-recyclerview listadapter android-listadapter


    【解决方案1】:
    abstract class BaseAdapter<T>(
     @LayoutRes
     val normalLayoutId: Int,
     @LayoutRes
     val loadingLayoutId: Int = R.layout.progress_loading,
     sm: (T, T) -> Boolean,
     val itemsCells: ArrayList<T?> = ArrayList()
    ) : ListAdapter<T, RecyclerView.ViewHolder>(CustomDiffCallbac(sm)) {
    val VIEW_TYPE_ITEM = 0
    val VIEW_TYPE_LOADING = 1
    
    class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
    
    class LoadingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
    
    fun addData(dataViews: ArrayList<T>) {
        itemsCells.addAll(dataViews)
        this.submitList(itemsCells)
    }
    
    
    override fun getItemViewType(position: Int): Int {
        return if (itemsCells[position] == null) {
            VIEW_TYPE_LOADING
        } else {
            VIEW_TYPE_ITEM
        }
    }
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return if (viewType == Constant.VIEW_TYPE_ITEM) {
            val view =
                LayoutInflater.from(parent.context).inflate(normalLayoutId, parent, false)
            ItemViewHolder(view)
        } else {
            val view =
                LayoutInflater.from(parent.context).inflate(loadingLayoutId, parent, false)
            LoadingViewHolder(view)
        }
    }
    
    fun addLoadingView() {
        itemsCells.add(null)
        submitList(itemsCells)
        notifyItemInserted(itemsCells.size-1)
    }
    
    fun removeLoadingView() {
        if (itemsCells.size != 0) {
            val index = itemsCells.size - 1
            itemsCells.removeAt(index)
           submitList(itemsCells)
            notifyItemRemoved(index)
        }
    }
    
    fun clearItems() {
        itemsCells.clear()
        submitList(itemsCells)
    }
    
    class CustomDiffCallbac<T>(val sm: (T, T) -> Boolean) : DiffUtil.ItemCallback<T>() {
        override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
            return sm(oldItem, newItem)
        }
    
    
        @SuppressLint("DiffUtilEquals")
        override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
            return oldItem == newItem
        }
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-01
      • 2013-09-30
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多