【问题标题】:Generic list in PagedListAdapterPagedListAdapter 中的通用列表
【发布时间】:2018-01-17 16:34:03
【问题描述】:

我想使用泛型类作为PagingList<>中的项目

interface GenericInterface{}
class GenericImplementation: GenericInterface{}

作为 Kotlin 文档状态:here 继承 in list 是不可能的,尽管我可以声明 T 的 Parameter 的泛型类型

public abstract class PagedListAdapter<T, VH extends RecyclerView.ViewHolder>

喜欢

class MAdapter: PagedListAdapter<GenericInterface, MAdapter.ViewHolder>(DIFF_CALLBACK){...}

我无法将通用列表传递给它

mAdapter.setList(listOfGenericImplementation)

因为outin 修饰符在类型投影中不被接受

PagedListAdapter<in/out GenericInterface, ..>(..){...}

有什么解决方法吗?

【问题讨论】:

  • @Kiskae 我看到了你的相关回答,可以参考我的问题吗?

标签: android kotlin generic-collections android-architecture-components


【解决方案1】:

好的,所以我遇到了同样的问题,但除了这个问题之外找不到任何东西,但过了一会儿我想通了,我这样做的方法是在你自己的类中定义泛型,然后将它传递给PagedListAdapter,例如:

你可以这样启动它:

var adapter: MAdapter<GenericImplementation, MAdapter.ViewHolder>

然后您的适配器类将如下所示:

class MAdapter<T : GenericInterface, VH : RecyclerView.ViewHolder> : PagedListAdapter<T, VH>(
    object : DiffCallback<T>() {
        override fun areItemsTheSame(oldItem: T, newItem: T): Boolean =
                oldItem.id == newItem.id

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

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH = 
                MAdapter.ViewHolder(parent)

    override fun onBindViewHolder(holder: VH, position: Int) {
        holder.bindTo(getItem(position)!!)
    }
}

如您所见,DiffCallback 必须是内联的,而不是将其放入伴随对象中的规范。

【讨论】:

    【解决方案2】:

    我也面临同样的问题。在将 Java POJO 重写为数据类时,我面临 Kotlin 数据类的受限继承问题,以便在具有多个 ViewHolder 的单个 PageListAdapter 的多个数据类型中使用。但是在 Kotlin 1.1 版之后,我们可以开始将接口实现为继承。但是使用这种模式,我们还必须使用关键字'as'对数据类和视图模型进行显式转换。结合@Anthony Cannon 对通用类 T 的回答,我可以让它工作。但我仍然不知道 IDE 在使用 Generic RecyclerView.ViewHolder 时显示错误并需要显式转换的原因。

    下面是我的代码。

    没有任何内容的空界面 - 超级 界面超级 数据类 TypeA 实现 Abstract

    data class TypeA (val someValueA: someValueA): Super
    

    数据类 TypeB 实现抽象

        data class TypeB (val someValueB: someValueB): Super
    

    PagedListAdapter 用于处理多个 Data Class 和多个 ViewHolder

    class CustomPagedListAdapterV2<T : Super, VH : RecyclerView.ViewHolder> internal constructor(private var controller: Controller) :
        CustomPagedListAdapterV2<T , VH>(object : DiffUtil.ItemCallback<T>() {
            override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
                return false
            }
    
            override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
                //            TODO :
                return false
            }
        }) {     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.layout_adapter_type_a, parent, false) // return TypeBListViewHolder(itemView, controller) as VH //depend on your own implementation
        return TypeAListViewHolder(itemView, controller) as VH
    }
    override fun onBindViewHolder(holder: VH, position: Int) { // (holder as TypeAListViewHolder).bindModel(getItem(position) as TypeB) //depend on your own implementation 
        (holder as TypeAListViewHolder).bindModel(getItem(position) as TypeA)
    
    }
    

    }

    从 Fragment/Activity 的 ViewModel 初始化 PagedListAdapter

        private lateinit var mAdapter: CustomPagedListAdapterV2<Super, RecyclerView.ViewHolder>
        viewModel.liveData.observe(viewLifecycleOwner, Observer { t ->
            mAdapter.submitList(t as PagedList<Super>)
    
        })
    

    说明

    【讨论】:

      【解决方案3】:
      abstract class DiffUtilPagedListAdapter<T : PagingComparable<T>, VH : BaseBindingViewHolder<T>> :
      PagedListAdapter<T, VH>
      

      适配器类将接受一个实现接口的类:PagingComparable,diff util方法将在实现该接口的类内部调用。

      适配器会很短很漂亮,如下所示

      class TransactionAdapter :
      DiffUtilPagedListAdapter<Transaction, TransactionAdapter.TransactionViewHolder>() {
      
      class TransactionViewHolder(override val binding: ItemTransactionBinding) :
          BaseBindingViewHolder<Transaction>(binding) {
      
          override fun bind(data: Transaction) {
              binding.transaction = data
          }
      }
      
      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionViewHolder {
          return TransactionViewHolder(createBinding(R.layout.item_transaction, parent))
      }}
      

      使用分页和MVVM以及数据绑定,节省时间!

      您可以阅读更多here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多