-
-
Save programmerr47/710f3bbbd1dd13cf7fbcb075e1c923fd to your computer and use it in GitHub Desktop.
Base adapter that holds all delegates and differFactory for producing diffs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open class DelegatesAdapter<I : Any>( | |
private val differFactory: (RecyclerView.Adapter<*>) -> ListDiffer<I>, | |
vararg delegates: ItemDelegate<out I, *> | |
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { | |
private val delegatesIndexMap: Map<Class<*>, Int> | |
private val delegatesList: List<ItemDelegate<I, RecyclerView.ViewHolder>> | |
private val listDiffer: ListDiffer<I> by lazy { differFactory(this) } | |
val items: List<I> get() = listDiffer.currentList | |
constructor(vararg delegates: ItemDelegate<out I, *>): this({ SyncListDiffer(it) }, *delegates) | |
init { | |
val map = mutableMapOf<Class<*>, Int>() | |
delegates.forEachIndexed { index, delegate -> | |
if (map.put(delegate.itemType(), index) != null) { | |
throw IllegalArgumentException() | |
} | |
} | |
delegatesIndexMap = map | |
delegatesList = delegates.map { | |
@Suppress("UNCHECKED_CAST") | |
it as? ItemDelegate<I, RecyclerView.ViewHolder> | |
?: throw IllegalArgumentException() | |
} | |
} | |
override fun getItemViewType(position: Int): Int = delegatesIndexMap[items[position]::class.java] | |
?: throw IllegalStateException("There is no delegate for item with type: ${items[position]::class.java}") | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = delegatesList[viewType].createVewHolder(parent) | |
override fun getItemCount() = items.size | |
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { | |
delegatesList[getItemViewType(position)].bindView(position, items[position], holder) | |
} | |
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) { | |
if (payloads.isEmpty()) { | |
super.onBindViewHolder(holder, position, payloads) | |
} else { | |
delegatesList[getItemViewType(position)].bindView(position, items[position], holder, payloads) | |
} | |
} | |
fun updateItem(old: I, new: I) { | |
val newList = items.toMutableList() | |
if (newList.updateFirst(new, { it == old })) { | |
submitList(newList) | |
} | |
} | |
fun submitList(list: List<I>) = listDiffer.submitList(list) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment