Search code examples
android-recyclerviewandroid-databindingandroidxgeneric-type-argumentandroid-listadapter

No type argument expected for ListAdapter - How to create separated ViewHolder files in AndroidX?


I've been learning about AndroidX and I would like to create a non nested ViewHolder inside my own Adapter class. So far I was doing something like

MainAdapter.kt

class MainAdapter : ListAdapter<MainResponse, MainAdapter.MainViewHolder>(MainDiffCallback()) {

  //onCreate
  //onBind
  //...

  class MainViewHolder(
        private val binding: ListItemMainBinding
    ) : RecyclerView.ViewHolder(binding.root) {

        fun bind(listener: View.OnClickListener) {
            with(binding) {
                this.listener = listener
            }
        }
    }
}

And now I would like to create them as separated files, like

MainAdapter.kt

class MainAdapter : ListAdapter<MyObject, MainViewHolder>(MainDiffCallback()) {
  //onCreate
  //onBind
  //...
}

MainViewHolder.kt

class MainViewHolder(private val binding: ListItemMainBinding): RecyclerView.ViewHolder(binding.root) {

    fun bind(listener: View.OnClickListener, manufacturer: String, color: Int) {
        with(binding) {
            binding.listener = listener
        }
    }
}

Using different files, I'm not sure how this is going to be declared on MainAdapter. This class MainAdapter : ListAdapter<MainResponse, MainViewHolder> returns me a non compiling error saying No type argument expected for ListAdapter. What's the correct syntax or approach to solve this problem?


Solution

  • Make sure that you are using the correct recycler view ListAdapter:

    import androidx.recyclerview.widget.ListAdapter
    

    Instead of this:

    import android.widget.ListAdapter  // This does not have type argument
    

    Code should stay as follows:

    MainAdapter.kt

    class MainAdapter : ListAdapter<MainResponse, MainViewHolder>(MainDiffCallback()) {
    
    }
    
    

    MainDiffCallback.kt

    class MainDiffCallback : DiffUtil.ItemCallback<MainResponse>() {
    
        override fun areItemsTheSame(
            oldItem: MainResponse,
            newItem: MainResponse
        ): Boolean {
            return oldItem == newItem
        }
    
        override fun areContentsTheSame(
            oldItem: MainResponse,
            newItem: MainResponse
        ): Boolean {
            return oldItem.image == newItem.image
        }
    }
    

    MainViewHolder.kt

    class MainViewHolder(private val bind: ListItemMainBinding) : BaseViewHolder<View.OnClickListener>(bind) {
    
        override fun onBind(listener: View.OnClickListener) {
            bind.listener = listener
        }
    }
    

    Also taking the opportunity to extend an abstract BaseViewHolder

    BaseViewHolder.kt

    abstract class BaseViewHolder<T>(bind :
                                             ViewDataBinding
    ) : RecyclerView.ViewHolder(bind.root) {
    
        abstract fun onBind(data: T)
    }