Skip to content

Instantly share code, notes, and snippets.

@n0m0r3pa1n
Created July 7, 2022 08:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n0m0r3pa1n/d8b82b61a59df3422ea55a3d62bd5f36 to your computer and use it in GitHub Desktop.
Save n0m0r3pa1n/d8b82b61a59df3422ea55a3d62bd5f36 to your computer and use it in GitHub Desktop.
ListAdapterStrategy for Android mobile and TV
class MobileListAdapterStrategy<T : Any, VH : RecyclerView.ViewHolder>(
override val adapter: RecyclerView.Adapter<VH>,
private val diffCallback: DiffUtil.ItemCallback<T>
) : ListAdapterStrategy<T, VH> {
private val listAdapter = object : ListAdapter<T, VH>(diffCallback) {
fun getItemWithPosition(position: Int) = getItem(position)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
return this.onCreateViewHolder(parent, viewType)
}
override fun onBindViewHolder(holder: VH, position: Int) {
return this.onBindViewHolder(holder, position)
}
}
override val currentList: List<T> = listAdapter.currentList
override fun getItemCount(): Int = listAdapter.itemCount
override fun getItem(position: Int) = listAdapter.getItemWithPosition(position)
override fun submitList(newItems: List<T>) {
listAdapter.submitList(newItems)
}
}
class TvListAdapterStrategy<T : Any, VH : RecyclerView.ViewHolder>(
override val adapter: RecyclerView.Adapter<VH>,
private val diffCallback: DiffUtil.ItemCallback<T>
) : ListAdapterStrategy<T, VH> {
private val items = mutableListOf<T>()
override val currentList: List<T> = items
override fun getItemCount(): Int = items.size
override fun getItem(position: Int) = items[position]
override fun submitList(newItems: List<T>) {
val callback = object : DiffUtil.Callback() {
override fun getOldListSize(): Int = items.size
override fun getNewListSize(): Int = newItems.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
diffCallback.areItemsTheSame(
items[oldItemPosition], newItems[newItemPosition]
)
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
diffCallback.areContentsTheSame(
items[oldItemPosition], newItems[newItemPosition]
)
}
val utilDiff = DiffUtil.calculateDiff(callback)
items.clear()
items.addAll(newItems)
utilDiff.dispatchUpdatesTo(adapter)
}
}
abstract class MyCustomListAdapter<T : Any, VH : RecyclerView.ViewHolder>(
private val diffCallback: DiffUtil.ItemCallback<T>
) : RecyclerView.Adapter<VH>(), KoinComponent {
private val getDeviceType: GetDeviceType by inject()
private val isTv: Boolean
get() = getDeviceType() == DeviceType.TV
private val listAdapterStrategy by lazy {
if (isTv) {
TvListAdapterStrategy<T, VH>(
this,
diffCallback
)
} else {
MobileListAdapterStrategy(
this,
diffCallback
)
}
}
val currentList: List<T> = listAdapterStrategy.currentList
override fun getItemCount(): Int = listAdapterStrategy.getItemCount()
fun getItem(position: Int) = listAdapterStrategy.getItem(position)
fun submitList(newItems: List<T>) = listAdapterStrategy.submitList(newItems)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment