title: RecyclerView with multiple view types with Generics
body: <p>I'm trying to achieve multiple view types in a recycler view using a generic base view holder.</p>
  
  <p>The BaseViewHolder class is</p>
  
  <pre><code>abstract class BaseViewHolder&lt;T&gt;(itemView: View) : RecyclerView.ViewHolder(itemView) {
      abstract fun bind(item: T)
  }
  </code></pre>
  
  <p>Then I created a view holder class for a specific view type</p>
  
  <pre><code>inner class CarouselViewHolder(itemView: View) : BaseViewHolder&lt;HomeCarousel&gt;(itemView) {
      override fun bind(item: HomeCarousel) {
      }
  }
  </code></pre>
  
  <p>I'm getting an error when accessing this bind function from fun onBindViewHolder method.</p>
  
  <p><strong>Out-projected type 'BaseViewHolder&lt;*>' prohibits the use of 'public abstract fun bind(item: T):</strong></p>
  
  <pre><code> override fun onBindViewHolder(holder: BaseViewHolder&lt;*&gt;, position: Int) {
      val element = data[position]
      when (element) {
          is HomeCarousel -&gt; {
              holder.bind(element)
          }
          else -&gt; throw java.lang.IllegalArgumentException("Invalid binding")
      }
  }
  </code></pre>
  
  <p>Getting error at</p>
  
  <pre><code>       holder.bind(element)
  </code></pre>
  
  <p>This is my entire Adapter class</p>
  
  <pre><code>class HomePageRecylerAdapter(private val data: ArrayList&lt;Any&gt;) : RecyclerView.Adapter&lt;BaseViewHolder&lt;*&gt;&gt;() {
  
  companion object {
      const val typeCarousel = 0
  }
  
  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder&lt;*&gt; {
      return when (viewType) {
          typeCarousel -&gt; {
              val view =
                  LayoutInflater.from(parent.context).inflate(R.layout.recycler_item_home_carasoul, parent, false)
              CarouselViewHolder(view)
          }
          else -&gt; throw IllegalArgumentException("Invalid view type")
      }
  
  }
  
  override fun getItemCount() = data.size
  
  override fun onBindViewHolder(holder: BaseViewHolder&lt;*&gt;, position: Int) {
      val element = data[position]
      when (element) {
          is HomeCarousel -&gt; {
              holder.bind(element)
          }
          else -&gt; IllegalArgumentException("Invalid binding")
      }
  }
  
  
  
  override fun getItemViewType(position: Int): Int {
      val element = data[position]
      return when (element) {
          is HomeCarousel -&gt; typeCarousel
          else -&gt; throw IllegalArgumentException("Invalid type of data {$position}")
      }
  }
  inner class CarouselViewHolder(itemView: View) : BaseViewHolder&lt;HomeCarousel&gt;(itemView) {
      override fun bind(item: HomeCarousel) {
      }
  }
  }
  abstract class BaseViewHolder&lt;T&gt;(itemView: View) : 
  RecyclerView.ViewHolder(itemView) {
     abstract fun bind(item: T)
  } 
  </code></pre>