'Making Adapter class work with different items Kotlin

How can i make "ExampleAdapter" a generic class in order to make it work with multiple different items with just passing a specific itemBinding in it's parameters. Here's a code example:

class ExampleAdapter (var exampleList: MutableList<Example>): RecyclerView.Adapter<ExampleAdapter.ViewHolder>() {



class ViewHolder(var binding: ExampleItemBinding) : RecyclerView.ViewHolder(binding.root)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val binding = ExampleItemBinding.inflate(inflater)
    return ViewHolder(binding)
}


@SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {

}

override fun getItemCount(): Int = exampleList.size

}



Solution 1:[1]

Sealed classes are a good tool to use here.

Create a hierarchy for the data types that you want to include:

sealed interface AdapterItem
class Foo : AdapterItem
class Bar : AdapterItem

Then create matching hierarchy of ViewHolder types:

sealed class AdapterItemViewHolder(view: View) : RecyclerView.ViewHolder(view)

class FooViewHolder(view: View): AdapterItemViewHolder(view) {
  fun bind(foo: Foo) { TODO() }
}

class BarViewHolder(view: View): AdapterItemViewHolder(view) {
  fun bind(bar: Bar) { TODO() }
}

Then your adapter can take in AdapterItem (any type) and you can do exhaustive when expressions to ensure all the types are covered.

class FooBarAdapter(
  private val data: List<AdapterItem>
) : RecyclerView.Adapter<AdapterItemViewHolder>() {
  override fun getItemCount() = data.size

  override fun getItemViewType(position: Int) = when (data[position]) {
    is Foo -> FOO_ITEM
    is Bar -> BAR_ITEM
  }

  override fun onCreateViewHolder(
    parent: ViewGroup, 
    viewType: Int
  ): AdapterItemViewHolder {
    return when (viewType) {
      FOO_ITEM -> FooViewHolder(createFooView())
      BAR_ITEM -> BarViewHolder(createBarView())
      else -> throw IllegalStateException("Invalid view type $viewType")
    }
  }

  override fun onBindViewHolder(holder: AdapterItemViewHolder, position: Int) {
    when (val item = data[position]) {
      is Foo -> (holder as FooViewHolder).bind(item)
      is Bar -> (holder as BarViewHolder).bind(item)
    }
  }

  companion object {
    private const val FOO_ITEM = 1
    private const val BAR_ITEM = 2
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kevin Coppock