Skip to content

Instantly share code, notes, and snippets.

@polson
Last active December 6, 2020 07:23
Show Gist options
  • Save polson/30e4753225f56d90ab85741b3092979c to your computer and use it in GitHub Desktop.
Save polson/30e4753225f56d90ab85741b3092979c to your computer and use it in GitHub Desktop.
A ListAdapter that pre-caches its views on creation
class SmoothListAdapter(val context: Context) : ListAdapter<ListItem, ListItemViewHolder>(MyDiffCallback()) {
data class ListItem(val id: String, val text: String)
class ListItemViewHolder(view: View) : ViewHolder(view) {
fun populateFrom(listItem: ListItem) {
//TODO: populate your view
}
}
companion object {
const val NUM_CACHED_VIEWS = 5
}
private val asyncLayoutInflater = AsyncLayoutInflater(context)
private val cachedViews = Stack<View>()
init {
//Create some views asynchronously and add them to our stack
for (i in 0..NUM_CACHED_VIEWS) {
asyncLayoutInflater.inflate(R.layout.list_item, null) { view, layoutRes, viewGroup ->
cachedViews.push(view)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder {
//Use the cached views if possible, otherwise if we ran out of cached views inflate a new one
val view = if (cachedViews.isEmpty()) {
LayoutInflater.from(context).inflate(R.layout.list_item, parent, false)
} else {
cachedViews.pop().also { it.layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT) }
}
return ListItemViewHolder(view)
}
override fun onBindViewHolder(viewHolder: ListItemViewHolder, position: Int) =
viewHolder.populateFrom(getItem(position))
class MyDiffCallback : DiffUtil.ItemCallback<ListItem>() {
override fun areItemsTheSame(firstItem: ListItem, secondItem: ListItem) =
firstItem.id == secondItem.id
override fun areContentsTheSame(firstItem: ListItem, secondItem: ListItem) =
firstItem == secondItem
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment