我正在使用数据绑定来设置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
。
有什么想法吗?
答案 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
,尤其是。
这有意义吗?可能不是这个问题,但我从那里开始。在不了解整个背景的情况下很难准确地告诉你这个问题,但这可能是你的问题。
如果不您的问题,您能否说明在执行期间您对availableWidth
,px
和margin
的价值是什么?