对数据绑定

时间:2017-11-07 07:03:31

标签: android android-recyclerview kotlin android-databinding android-binding-adapter

我正在使用数据绑定来设置RecyclerView。这是绑定适配器:

fun setRecyclerDevices(recyclerView: RecyclerView, items: List<Device>, itemBinder: MultipleTypeItemBinder,
                                   listener: BindableListAdapter.OnClickListener<Device>?) {

        var adapter = recyclerView.adapter as? DevicesBindableAdapter
        if (adapter == null) {
            val spannedGridLayoutManager = SpannedGridLayoutManager(orientation = SpannedGridLayoutManager.Orientation.VERTICAL,
                    spans = getSpanSizeFromScreenWidth(recyclerView.context, recyclerView))
            recyclerView.layoutManager = spannedGridLayoutManager
            recyclerView.addItemDecoration(SpaceItemDecorator(left = 15, top = 15, right = 15, bottom = 15))
            adapter = DevicesBindableAdapter(items, itemBinder)
            adapter.setOnClickListener(listener)
            recyclerView.adapter = adapter
        } else {
            adapter.setOnClickListener(listener)
            adapter.setItemBinder(itemBinder)
            adapter.setItems(items)
        }
    }

getSpanSizeFromScreenWidth需要回收者的宽度来进行一些计算。但它始终返回0

我尝试像这样应用ViewTreeObserver

recyclerView.viewTreeObserver.addOnGlobalLayoutListener(object: ViewTreeObserver.OnGlobalLayoutListener {

                override fun onGlobalLayout() {
                    recyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                    val spannedGridLayoutManager = SpannedGridLayoutManager(orientation = SpannedGridLayoutManager.Orientation.VERTICAL,
                            spans = getSpanSizeFromScreenWidth(recyclerView.context, recyclerView))
                    recyclerView.layoutManager = spannedGridLayoutManager
                }
            })

或者像这样使用post

recyclerView.post({
                val spannedGridLayoutManager = SpannedGridLayoutManager(orientation = SpannedGridLayoutManager.Orientation.VERTICAL,
                        spans = getSpanSizeFromScreenWidth(recyclerView.context, recyclerView))
                recyclerView.layoutManager = spannedGridLayoutManager
            })

getSpanSizeFormScreenWidth代码:

private fun getSpanSizeFromScreenWidth(context: Context, recyclerView: RecyclerView): Int {
        val availableWidth = recyclerView.width.toFloat()
        val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300f, context.resources.displayMetrics)
        val margin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 15f, context.resources.displayMetrics)
        return Math.max(1, Math.floor((availableWidth / (px + margin)).toDouble()).toInt()) * DevicesBindableAdapter.WIDTH_UNIT_VALUE
    }

但尽管屏幕上显示0RecyclerView),它仍会返回0

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

在检查代码时,您的RecyclerView似乎可能没问题,但getSpanSizeFromScreenWidth中的逻辑可能不是。

看起来像这样:当Math.floor((availableWidth / (px + margin)).toDouble()).toInt()小于availableWidth时,(px + margin) 总是为0。这将导致getSpanSizeFromScreenWidth返回0

打破它:

  • Math.floor - 将double 向下舍入为整数
  • availableWidth / (px + margin) - 将是数字(availableWidth的一小部分)

因此,您有时会在较小的屏幕和/或较小密度的屏幕上获得0 ,尤其是

这有意义吗?可能不是这个问题,但我从那里开始。在不了解整个背景的情况下很难准确地告诉你这个问题,但这可能是你的问题。

如果您的问题,您能否说明在执行期间您对availableWidthpxmargin的价值是什么?