android - 使用数据绑定(bind)在 PagerAdapter 中回收 View

标签 android data-binding android-databinding

我一直在尝试在我的 PagerAdapter 中实现回收,多亏了 this question,我可以成功地做到这一点但是我遇到了一个问题,无法通过数据绑定(bind)来缓存 View 。

我试过这样,保持 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)
    }
}

但是,每当它第一次尝试使用回收 View 并调用 CustomBinding.bind(view) 时它崩溃是因为 View 必须有一个标签。我搜索过这个,但我找到的答案都没有完全解决我的问题。

我也试过保留 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))
}

我仍然会遇到同样的错误。我怎样才能像这样“回收”数据绑定(bind)对象?或者,如果我回收 View 本身,我如何将它们转换回绑定(bind)对象?

最佳答案

我猜你犯了一个简单的错误。 如果我错了,您可以纠正我,我尝试使用这个适配器并且它有效。

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
            }

我认为,您试图绑定(bind)到一个已经附加了 Binding 的 View 。因此它给了你一个错误。我所做的是检查任何以前的绑定(bind),如果存在则返回关联的绑定(bind)。

关于android - 使用数据绑定(bind)在 PagerAdapter 中回收 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50931464/

相关文章:

android - 如何从 kotlin 的构造函数中定义的 xml 中引用函数?

android - Data Binding EditText set null 被 set empty String 替换

c# - WPF 绑定(bind)到对象集合,按顺序存储在 C# 中的另一个集合中的 ID 排序

html - 数据绑定(bind) : value - parenthesis - observable

android - 使用 libvpx x86 android 构建项目失败并出现 undefined reference 错误

android - Android 中的连接拒绝错误

c# - 是否可以将两个源属性绑定(bind)到一个控件属性?

android - 结合 android ViewModel 和数据绑定(bind)的最佳实践

java - 将 textView 中的 double 值保存到变量

java - 如何在我的安卓应用中使用谷歌翻译 API