sad*_*dat 2 java generics android kotlin
我正在尝试编写一个通用的 recyclerview 适配器。我找到了几个例子。然而,仍然无法弄清楚如何实现通用适配器。我写的代码是,
open abstract class BaseAdapter<T : RecyclerView.ViewHolder>(private val onClickListener: View.OnClickListener, @LayoutRes private val layoutResource:Int) :
RecyclerView.Adapter<T>() {
var items: MutableList<Item> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T {
val layout = LayoutInflater.from(parent.context).inflate(layoutResource, parent, false)
layout.setOnClickListener(onClickListener)
return T(layout)
}
override fun getItemCount(): Int {
return items.size
}
}
Run Code Online (Sandbox Code Playgroud)
我在 line 处收到错误return T(layout)。错误是Expression 'T' of type 'Int' cannot be invoked as a function. The function 'invoke()' is not found。
我将类似的东西用于 ListAdapter 的通用 this (利用ViewBinding)
class BaseListAdapter<T>(
private val inflate: (layoutInflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean) -> ViewBinding,
private val bind: (item: T, binding: ViewBinding) -> Unit,
private val onClick: (item: T) -> Unit,
compareItems: (old: T, new: T) -> Boolean,
compareContents: (old: T, new: T) -> Boolean
) : ListAdapter<T, RecyclerView.ViewHolder>(DiffCallback(compareItems, compareContents)) {
var items = emptyList<T>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ItemViewHolder(inflate(LayoutInflater.from(parent.context), parent, false))
@Suppress("UNCHECKED_CAST")
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
bind(getItem(position), (holder as BaseListAdapter<T>.ItemViewHolder).binding)
}
internal fun setItems(items: List<T>) {
this.items = items
this.submitList(items)
}
inner class ItemViewHolder(val binding: ViewBinding) : RecyclerView.ViewHolder((binding).root) {
init {
binding.root.setOnClickListener { onClick(getItem(adapterPosition)) }
}
}
private class DiffCallback<K>(
private val compareItems: (old: K, new: K) -> Boolean,
private val compareContents: (old: K, new: K) -> Boolean
) : DiffUtil.ItemCallback<K>() {
override fun areItemsTheSame(old: K, new: K) = compareItems(old, new)
override fun areContentsTheSame(old: K, new: K) = compareContents(old, new)
}
}
Run Code Online (Sandbox Code Playgroud)
然后在片段/活动中,您可以像这样启动它(对于ViewBindingCustomer和RvCustomerBinding作为 ViewBinding)
val adapter = BaseListAdapter<Customer>(
{ li, parent, attach -> RvCustomerBinding.inflate(li, parent, attach) },
{ item, vb -> (vb as RvCustomerBinding).tvName.text = item.name },
{ item -> displayToast(requireContext(), "Customer: ${item.name}") },
{ old, new -> old.id == new.id },
{ old, new -> old == new }
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3129 次 |
| 最近记录: |