2

I want to use generic class as items in PagingList<>

interface GenericInterface{}
class GenericImplementation: GenericInterface{}

As Kotlin doc state: here inheritance in list isn't possible, although I can declare generic type of Parameter of T

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

like

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

I cannot pass generic list to it

mAdapter.setList(listOfGenericImplementation)

because out, in modifiers are not accepted in Type projections

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

Is there any workaround for this?

murt
  • 3,790
  • 4
  • 37
  • 48

3 Answers3

2

Ok so I had this same problem but couldn't find anything on it except this question, but after a while I figured it out and the way I did it was to define the generic in your own class and then pass it onto the PagedListAdapter, for example:

You would initiate it like this:

var adapter: MAdapter<GenericImplementation, MAdapter.ViewHolder>

And then your adapter class would look like this:

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)!!)
    }
}

As you can see the DiffCallback has to be inline instead of the norm of putting it in the companion object.

Anthony Cannon
  • 1,245
  • 9
  • 20
0

I also face same problem. While rewriting Java POJO into Data Classes, i face problem with restricted Inheritance on Kotlin Data Class to use in multiple Data Type for Single PageListAdapter with multiple ViewHolder. But after Kotlin version 1.1 , we can start implementing Interface as Inheritance. But using this pattern, we also have to need explicit cast on Data Classes and ViewModel using keyword 'as'.Combine with @Anthony Cannon answer on Generic Class T, I can able to make it work. But I still don't know the reason why IDE show error on using Generic RecyclerView.ViewHolder and needed explicit cast.

Below is my code.

Empty Interface with nothing in it - Super interface Super Data Class TypeA implementing Abstract

data class TypeA (val someValueA: someValueA): Super

Data Class TypeB implementing Abstract

    data class TypeB (val someValueB: someValueB): Super

PagedListAdapter for handling multiple Data Class and multiple 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)

}

}

Initializing PagedListAdapter from Fragment/Activity 's ViewModel

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

    })

Description

Htet Will
  • 21
  • 1
  • 5
0
abstract class DiffUtilPagedListAdapter<T : PagingComparable<T>, VH : BaseBindingViewHolder<T>> :
PagedListAdapter<T, VH>

The adapter class will accept a class which implements an interface: PagingComparable, the diff util method will be called inside the classes which implemented the interface.

the adapter will be very short and pretty like below

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))
}}

with the paging and MVVM and databinding, time saving!

you can read more here

Koma Yip
  • 5,359
  • 1
  • 11
  • 12