Skip to content

Instantly share code, notes, and snippets.

@iSanechek
Created June 1, 2018 23:28
Show Gist options
  • Select an option

  • Save iSanechek/bc26d8a1e8a366c016fb75ef30a32f82 to your computer and use it in GitHub Desktop.

Select an option

Save iSanechek/bc26d8a1e8a366c016fb75ef30a32f82 to your computer and use it in GitHub Desktop.
open class BaseAdapter<T>(diffcallback: DiffUtil.ItemCallback<T>) : PagedListAdapter<T, BaseViewHolder>(diffcallback) {
protected val delegateManager: DelegateManager<T> = DelegateManager()
protected fun useItemViewDelegateManager(): Boolean = delegateManager.delegateCount > 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder =
BaseViewHolder.createHolder(delegateManager.getItemViewDelegate(viewType).itemViewLayoutView)
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) =
convert(holder, getItem(position)!!)
override fun getItemViewType(position: Int): Int = if (!useItemViewDelegateManager())
super.getItemViewType(position)
else delegateManager.getItemViewType(getItem(position)!!, position)
fun convert(holder: BaseViewHolder, item: T) = delegateManager.convert(holder, item, holder.adapterPosition)
fun addItemViewDelegate(delegate: DelegateType<T>) = delegateManager.addDelegate(delegate)
fun addItemViewDelegate(viewTyoe: Int, delegate: DelegateType<T>) = delegateManager.addDelegate(viewTyoe, delegate)
}
class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
companion object {
fun createHolder(itemView: View): BaseViewHolder = BaseViewHolder(itemView)
fun createHolder(parent: ViewGroup, layout: Int): BaseViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(layout, parent, false)
return BaseViewHolder(itemView)
}
}
}
class DelegateManager<T> {
val delegates: SparseArrayCompat<DelegateType<T>> = SparseArrayCompat()
val delegateCount: Int
get() = delegates.size()
fun getItemViewType(item: T, position: Int): Int {
(0 until delegateCount)
.filter { delegates.valueAt(it).isItemViewType(item, position) }
.forEach { return delegates.keyAt(it) }
throw IllegalArgumentException(
"No ItemViewDelegate added that matches position = $position in data = $item source");
}
fun convert(holder: BaseViewHolder, item: T, position: Int) {
for (i in 0 until delegateCount) {
val delegate = delegates.valueAt(i)
if (delegate.isItemViewType(item, position)) {
delegate.convert(holder, item, position);
return@convert
}
}
throw IllegalArgumentException(
"No ItemViewDelegateManager added that matches position= $position in data = $item source")
}
fun addDelegate(delegate: DelegateType<T>): DelegateManager<T> {
for (i in 0 until delegateCount) {
if (delegates.valueAt(i).itemViewLayoutView == delegate.itemViewLayoutView) {
throw IllegalArgumentException("An ItemViewDelegate is already registered for the delegate = $delegate.")
}
// if (delegates.valueAt(i).itemViewLayoutId == delegate.itemViewLayoutId) {
// throw IllegalArgumentException("An ItemViewDelegate is already registered for the delegate = $delegate.")
// }
}
delegates.put(delegates.size(), delegate)
return this
}
fun addDelegate(viewType: Int, delegate: DelegateType<T>): DelegateManager<T> {
if (delegates.get(viewType) != null) {
throw IllegalArgumentException("An ItemViewDelegate is already registered for the viewType = $viewType. Already registered ItemViewDelegate is ${delegates.get(viewType)}")
}
delegates.put(viewType, delegate)
return this
}
fun removeDelegate(delegate: DelegateType<T>): DelegateManager<T> {
val indexToRemove = delegates.indexOfValue(delegate)
if (indexToRemove >= 0) {
delegates.removeAt(indexToRemove)
}
return this
}
fun removeDelegate(viewType: Int): DelegateManager<T> {
val indexToRemove = delegates.indexOfKey(viewType)
if (indexToRemove >= 0) {
delegates.removeAt(indexToRemove)
}
return this
}
fun getItemViewDelegate(viewType: Int): DelegateType<T> = delegates.get(viewType)
// fun getItemViewLayoutId(viewType: Int): Int = getItemViewDelegate(viewType).itemViewLayoutId
fun getItemViewType(delegate: DelegateType<T>): Int = delegates.indexOfValue(delegate)
}
interface DelegateType<in T> {
// val itemViewLayoutId: Int
val itemViewLayoutView: View
fun isItemViewType(item: T, position: Int): Boolean
fun convert(holder: BaseViewHolder, item: T, position: Int)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment