【问题标题】:Call getMeasuredWidth() or getWidth() for RecyclerView return 0 on data binding为 RecyclerView 调用 getMeasuredWidth() 或 getWidth() 在数据绑定上返回 0
【发布时间】:2017-11-07 07:03:31
【问题描述】:

我正在使用数据绑定来设置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
    }

但它仍然返回0,尽管我的RecyclerView 显示在屏幕上(不是0)。

有什么想法吗?

【问题讨论】:

  • 您能发布您的getSpanSizeFromScreenWidth 方法的代码吗?谢谢!
  • 刚刚添加 :) 之前没有放,因为没什么特别的^^

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


【解决方案1】:

在检查代码时,您的RecyclerView 可能实际上很好,但您在getSpanSizeFromScreenWidth 中的逻辑可能不是。

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


分解:

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

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

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


如果这不是你的问题,你能说一下你在执行期间对availableWidthpxmargin的价值是什么?

【讨论】:

  • 但我的问题是调试器 recycler.width 等于 0 而不是所有函数:/ 所以 availableWidth = 0, px= 825.0 and margin = 15.0
  • 也许我对小屏幕和密度的计算是错误的,你是对的,但这里我是在大屏幕和密度上进行测试,所以应该是正确的。但是谢谢,当这个固定时,我会看看更小的密度^^
  • 等等.. 我不知何故完全错过了Math.max(1, ...)。但这意味着最后一行必须解析为&lt;value_1_or_greater&gt; * DevicesBindableAdapter.WIDTH_UNIT_VALUE。如果你说它返回0,那么这意味着WIDTH_UNIT_VALUE 等于0 或者它是&gt; 0 and &lt; 0.5,可能导致它向下舍入到0。希望这会有所帮助。哈哈,如果没有,祝你好运!希望你能正常工作.. P.S.这个帖子可能有一些类似的想法可以尝试:stackoverflow.com/questions/3591784/…
  • 没有 getSpanSizeFromScreenWidth 总是返回 8,因为 WIDTH_UNIT_VALUE 等于 8 :) 但那是因为我的 recyclerView.width 总是返回 0 :( 我会继续挖掘,但谢谢你的输入 :)
猜你喜欢
  • 1970-01-01
  • 2017-06-13
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
相关资源
最近更新 更多