Skip to content

Instantly share code, notes, and snippets.

@sergei-lapin
Created August 5, 2021 06:57
Show Gist options
  • Save sergei-lapin/66d37fb628350334a5c378c9aebdb1df to your computer and use it in GitHub Desktop.
Save sergei-lapin/66d37fb628350334a5c378c9aebdb1df to your computer and use it in GitHub Desktop.
Full Supplier code
typealias ViewHolderProducer = (parent: ViewGroup, viewType: Int) -> RecyclerView.ViewHolder
typealias ViewHolderConsumer = (viewHolder: RecyclerView.ViewHolder, creationTimeNanos: Long) -> Unit
abstract class ViewHolderSupplier(
context: Context,
private val viewHolderProducer: ViewHolderProducer
) {
internal lateinit var viewHolderConsumer: ViewHolderConsumer
private val fakeParent: ViewGroup by lazy { FrameLayout(context) }
private val mainHandler: Handler = Handler(Looper.getMainLooper())
private val itemsCreated: MutableMap<Int, Int> = ConcurrentHashMap<Int, Int>()
private val itemsQueued: MutableMap<Int, Int> = ConcurrentHashMap<Int, Int>()
private val nanoTime: Long get() = System.nanoTime()
abstract fun start()
abstract fun enqueueItemCreation(viewType: Int)
abstract fun stop()
protected fun createItem(viewType: Int) {
val created = itemsCreated.getOrZero(viewType) + 1
val queued = itemsQueued.getOrZero(viewType)
if (created > queued) return
val holder: RecyclerView.ViewHolder
val start: Long
val end: Long
try {
start = nanoTime
holder = viewHolderProducer.invoke(fakeParent, viewType)
end = nanoTime
} catch (e: Exception) {
return
}
holder.setItemViewType(viewType)
itemsCreated[viewType] = itemsCreated.getOrZero(viewType) + 1
mainHandler.postAtFrontOfQueue { viewHolderConsumer.invoke(holder, end - start) }
}
internal fun setPrefetchBound(viewType: Int, count: Int) {
if (itemsQueued.getOrZero(viewType) >= count) return
itemsQueued[viewType] = count
val created = itemsCreated.getOrZero(viewType)
if (created >= count) return
repeat(count - created) { enqueueItemCreation(viewType) }
}
internal fun onItemCreatedOutside(viewType: Int) {
itemsCreated[viewType] = itemsCreated.getOrZero(viewType) + 1
}
private fun Map<Int, Int>.getOrZero(key: Int) = getOrElse(key) { 0 }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment