Skip to content

Instantly share code, notes, and snippets.

@baleen37
Created July 11, 2017 07:31
Show Gist options
  • Save baleen37/2ec9a86aaf3437750a8841eb87c132d0 to your computer and use it in GitHub Desktop.
Save baleen37/2ec9a86aaf3437750a8841eb87c132d0 to your computer and use it in GitHub Desktop.
delegate adapter
abstract class AbsDelegateAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val delegatesManager = DelegateAdapterManager<T>()
abstract var items: T
override fun onBindViewHolder(viewHolder: ViewHolder?, position: Int) {
delegatesManager.onBindViewHolder(viewHolder, items, position)
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
return delegatesManager.onCreateViewHolder(parent, viewType)
}
override fun getItemViewType(position: Int): Int {
return delegatesManager.getItemViewType(items, position)
}
}
interface AdapterDelegate<T> {
fun isForViewType(items: T, position: Int): Boolean
fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder
fun onBindViewHolder(holder: ViewHolder, items: T, position: Int)
}
class DelegateAdapterManager<T> {
var delegates = SparseArrayCompat<AdapterDelegate<T>>()
fun addDelegate(adapterDelegate: AdapterDelegate<T>) {
val viewType = delegates.size()
delegates.append(viewType, adapterDelegate)
}
fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val delegate = getDelegateForViewType(viewType) ?:
throw NullPointerException("getDelegateForViewType($viewType) is null")
return delegate.onCreateViewHolder(parent, viewType)
}
fun onBindViewHolder(viewHolder: ViewHolder?, items: T, position: Int) {
viewHolder?.let {
val delegate = getDelegateForViewType(viewHolder.itemViewType) ?:
throw NullPointerException("getDelegateForViewType(${viewHolder.itemViewType}) is null")
delegate.onBindViewHolder(viewHolder, items, position)
}
}
private fun getDelegateForViewType(viewType: Int): AdapterDelegate2<T>? {
return delegates.get(viewType)
}
fun getItemViewType(items: T, position: Int): Int {
if (items == null) {
throw NullPointerException("Items data source is null!")
}
val delegatesCount = delegates.size()
for (i in 0..delegatesCount - 1) {
val delegate = delegates.valueAt(i)
if (delegate.isForViewType(items, position)) {
return delegates.keyAt(i)
}
}
throw NullPointerException(
"No AdapterDelegate added that matches position=$position in data source")
}
}
class PackageDetailListAdapter(val context: Context,
override var items: List<DisplayItem> = listOf())
: AbsDelegateAdapter<List<DisplayItem>>() {
val packageCourseAddButtonDelegateAdapter = PackageCourseAddButtonDelegate(context)
val packageCourseItemDelegateAdapter = PackageCourseItemDelegate(context)
init {
delegatesManager.addDelegate(packageCourseAddButtonDelegateAdapter)
delegatesManager.addDelegate(packageCourseItemDelegateAdapter)
}
override fun getItemCount(): Int {
return items.size
}
}
interface DisplayItem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment