使用数据绑定在 PagerAdapter 中回收视图
Recycle views in PagerAdapter with data binding
我一直在尝试在我的 PagerAdapter 中实现回收,多亏了 this question 我可以成功地做到这一点,但是我 运行 遇到了通过数据绑定缓存视图的问题。
我试过这样,保持一个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)
}
}
但是,每当它第一次尝试使用回收视图并调用 CustomBinding.bind(view)
时,它就会崩溃,因为视图必须有一个标签。我搜索了这个,但我找到的 none 个答案已经完全解决了我的问题。
我也试过保留 Stack<CustomBinding>
,但问题是我不确定如何处理 destroyItem
方法。因为如果我这样做:
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
recycledViews.add(CustomBinding.bind(view))
}
我仍然会遇到同样的错误。我怎样才能 "recycle" 这样的数据绑定对象?或者,如果我回收视图本身,如何将它们转换回绑定对象?
我想你犯了一个简单的错误。
如果我错了你可以纠正我,我试过这个适配器并且它有效。
val demoAdapter = object : PagerAdapter() {
private var recycledViews: Stack<View> = Stack()
var items: List<String> = ArrayList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val binding = inflateOrRecycle(container)
container.addView(binding.root)
return binding.root
}
private fun inflateOrRecycle(container: ViewGroup): DemoItemBinding {
val inflater = LayoutInflater.from(container.context)
return if (recycledViews.isEmpty()) {
DemoItemBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
val custBinding = DataBindingUtil.getBinding<DemoItemBinding>(view)
if(custBinding == null)
DemoItemBinding.bind(view)
else
custBinding
}
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
recycledViews.add(view)
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return `object` is View && view.equals(`object`)
}
override fun getCount(): Int {
return 4
}
}
我从你的代码中更改的部分是这个
return if (recycledViews.isEmpty()) {
CustomBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
CustomBinding.bind(view)
}
到
return if (recycledViews.isEmpty()) {
DemoItemBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
val custBinding = DataBindingUtil.getBinding<DemoItemBinding>(view)
if(custBinding == null)
DemoItemBinding.bind(view)
else
custBinding
}
我认为,您试图绑定到一个已经附加了 Binding 的视图。因此它给了你一个错误。我所做的是检查任何以前的绑定,如果它存在 return 关联的绑定。
我一直在尝试在我的 PagerAdapter 中实现回收,多亏了 this question 我可以成功地做到这一点,但是我 运行 遇到了通过数据绑定缓存视图的问题。
我试过这样,保持一个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)
}
}
但是,每当它第一次尝试使用回收视图并调用 CustomBinding.bind(view)
时,它就会崩溃,因为视图必须有一个标签。我搜索了这个,但我找到的 none 个答案已经完全解决了我的问题。
我也试过保留 Stack<CustomBinding>
,但问题是我不确定如何处理 destroyItem
方法。因为如果我这样做:
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
recycledViews.add(CustomBinding.bind(view))
}
我仍然会遇到同样的错误。我怎样才能 "recycle" 这样的数据绑定对象?或者,如果我回收视图本身,如何将它们转换回绑定对象?
我想你犯了一个简单的错误。 如果我错了你可以纠正我,我试过这个适配器并且它有效。
val demoAdapter = object : PagerAdapter() {
private var recycledViews: Stack<View> = Stack()
var items: List<String> = ArrayList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val binding = inflateOrRecycle(container)
container.addView(binding.root)
return binding.root
}
private fun inflateOrRecycle(container: ViewGroup): DemoItemBinding {
val inflater = LayoutInflater.from(container.context)
return if (recycledViews.isEmpty()) {
DemoItemBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
val custBinding = DataBindingUtil.getBinding<DemoItemBinding>(view)
if(custBinding == null)
DemoItemBinding.bind(view)
else
custBinding
}
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val view = `object` as View
container.removeView(view)
recycledViews.add(view)
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return `object` is View && view.equals(`object`)
}
override fun getCount(): Int {
return 4
}
}
我从你的代码中更改的部分是这个
return if (recycledViews.isEmpty()) {
CustomBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
CustomBinding.bind(view)
}
到
return if (recycledViews.isEmpty()) {
DemoItemBinding.inflate(inflater, container, false)
} else {
val view = recycledViews.pop()
val custBinding = DataBindingUtil.getBinding<DemoItemBinding>(view)
if(custBinding == null)
DemoItemBinding.bind(view)
else
custBinding
}
我认为,您试图绑定到一个已经附加了 Binding 的视图。因此它给了你一个错误。我所做的是检查任何以前的绑定,如果它存在 return 关联的绑定。