Skip to content

Instantly share code, notes, and snippets.

@ildar2
Created February 4, 2020 05:15
Show Gist options
  • Save ildar2/b07a4632ac8470987d8badac5a7a69d0 to your computer and use it in GitHub Desktop.
Save ildar2/b07a4632ac8470987d8badac5a7a69d0 to your computer and use it in GitHub Desktop.
Android RecyclerView.Adapter for creating dynamic ui with lists of items, buttons, labels etc.
package clean.utils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
/**
* Класс для работы со списками
* Может работать с несколькими видами элементов
* В качестве viewType выступает лэйаут элемента [DisplayItem.layout]
* поэтому, в пределах одного списка все лэйауты должны быть уникальными
*
* Для работы нужно обозначить DTO с их лэйаутами и переопределить [createViewHolder]
* Все элементы должны имплементить интерфейс [DisplayItem]
*/
abstract class DisplayAdapter(
items: List<DisplayItem> = emptyList()
) : RecyclerView.Adapter<DisplayViewHolder<DisplayItem>>() {
var items = items
set(value) {
field = value
notifyDataSetChanged()
}
override fun getItemViewType(position: Int) = items[position].layout
@Suppress("UNCHECKED_CAST")
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): DisplayViewHolder<DisplayItem> = createViewHolder(
LayoutInflater.from(parent.context).inflate(
viewType,
parent,
false
), viewType
) as DisplayViewHolder<DisplayItem>
/**
* Erased type for brevity, item should always implement [DisplayItem]
*/
abstract fun createViewHolder(view: View, viewType: Int): DisplayViewHolder<*>
override fun getItemCount() = items.size
override fun onBindViewHolder(holder: DisplayViewHolder<DisplayItem>, position: Int) =
holder.bind(items[position])
}
/**
* Общий интерфейс для элементов отображения в списке адаптера
*/
abstract class DisplayItem(val layout: Int)
/**
* Общий интерфейс для вьюхолдеров
* Связывает элементы [DisplayItem] и их вьюшки [DisplayItem.layout]
* Обычно лучше делать inner-классом элемента для понятности, но не обязательно
*/
abstract class DisplayViewHolder<E>(
override val containerView: View
) : RecyclerView.ViewHolder(containerView), LayoutContainer {
abstract fun bind(item: E)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment