Created
July 7, 2022 08:52
-
-
Save n0m0r3pa1n/d8b82b61a59df3422ea55a3d62bd5f36 to your computer and use it in GitHub Desktop.
ListAdapterStrategy for Android mobile and TV
This file contains hidden or 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
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