Created
February 4, 2020 05:15
-
-
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.
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
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