This is my solution, which uses an abstract class that will extend your adapter
abstract class HeaderAdapter<T : RecyclerView.ViewHolder>(var headerView: View) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { var headerView: View = headerView set(value) { notifyItemChanged(HEADER_POSITION) field = value } companion object { const val TYPE_HEADER = -1 const val HEADER_POSITION = 0 } abstract val itemCountWithoutHeader: Int abstract fun getViewHolder(parent: ViewGroup, viewType: Int): T abstract fun onBindItemViewHolder(holder: T, position: Int) open fun getItemsItemViewType(position: Int): Int { return super.getItemViewType(position) } final override fun getItemCount(): Int = itemCountWithoutHeader + 1 final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return if (viewType == TYPE_HEADER) HeaderHolder(headerView) else getViewHolder(parent, viewType) } final override fun getItemViewType(position: Int): Int { return if (position == HEADER_POSITION) TYPE_HEADER else getItemsItemViewType(position) } final override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { if (position != HEADER_POSITION) onBindItemViewHolder(holder as T, position-1) } class HeaderHolder(itemView: View) : RecyclerView.ViewHolder(itemView) }