首页 > 解决方案 > Kotlin 泛型 - 调用伴随对象方法

问题描述

我有两个RecyclerView.ViewAdapter非常相同的实现,我想将它们统一为具有类型参数的单个类T。唯一的区别是一类使用ImageViewHolder,另一类使用VideoViewHolder

class ImageGridAdapter : RecyclerView.Adapter<ImageViewHolder>() {

    private val asyncListDiffer = AsyncListDiffer<Image>(this, diffCallback)

    init { setHasStableIds(true) }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
        // How to call this companion object method from a generic class?
        return ImageViewHolder.from(parent)
    }

    override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
        holder.bind(asyncListDiffer.currentList[position], dragSelector, lifecycle.get())
    }

    fun submit(list: List<Image>) = asyncListDiffer.submitList(list)

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

    override fun getItemId(position: Int): Long {
        return asyncListDiffer.currentList[position].id
    }
}

问题:如何*ViewHolder.from(parent)在 Kotlin 中以通用方式调用?我真的不想创建两个单独的类只是为了覆盖一个方法!

标签: androidkotlin

解决方案


您可以使用组合而不是继承,将 ViewHolder 创建委托给作为构造函数参数传递的函数:

class GenericGridAdapter<VH : ViewHolder>(private val viewHolderCreator : (ViewGroup) -> VH) : RecyclerView.Adapter<VH>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        return viewHolderCreator.invoke(parent)
    }

    // Other common methods
}

// And then:

val imageGridAdapter = GenericGridAdapter { ImageViewHolder.from(it) }
val videoGridAdapter = GenericGridAdapter { VideoViewHolder.from(it) }

// or using method references:

val imageGridAdapter = GenericGridAdapter((ImageViewHolder)::from)
val videoGridAdapter = GenericGridAdapter((VideoViewHolder)::from)

推荐阅读