I've been trying to implement recycling in my PagerAdapter, which I could do successfully thanks to this question however I'm running into a problem to cache the views with data binding.
I have tried like this, keeping a Stack<View>
:
class CustomAdapter : PagerAdapter() {
private var recycledViews: Stack<View> = Stack()
var items: List<Item> = ArrayList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val binding = inflateOrRecycle(container)
binding.item = items[position]
binding.handler = this
container.addView(binding.root)
return binding.root
}
private fun inflateOrRecycle(container: ViewGroup): CustomBinding {
val inflater = LayoutInflater.from(container.context)
return if (recycledViews.isEmpty()) {
CustomBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
CustomBinding.bind(view)
}
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
recycledViews.add(view)
}
}
However, whenever it tries to use a recycled view for the first time and calls CustomBinding.bind(view)
it crashes because the view must have a tag. I've searched this, but none of the answers I've found have quite fixed my problem.
I've also tried keeping a Stack<CustomBinding>
, but the problem is I'm not sure how to handle the destroyItem
method. Because if I do:
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
recycledViews.add(CustomBinding.bind(view))
}
I'll still get the same error. How can I "recycle" data binding objects like this? Or, if I recycle the views themselves, how do I convert them back to binding objects?