Вызовите getMeasuredWidth() или getWidth() для RecyclerView, возвращающего 0 при привязке данных
Я использую привязку данных для настройки 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
).
Есть идеи?
1 ответ
При проверке кода выясняется, что ваш RecyclerView
может на самом деле все в порядке, но ваша логика в getSpanSizeFromScreenWidth
может не быть.
Это выглядит так: Math.floor((availableWidth / (px + margin)).toDouble()).toInt()
всегда будет 0, когда availableWidth
меньше чем (px + margin)
, Это приведет к getSpanSizeFromScreenWidth
возвращать 0
,
Разбивая это:
Math.floor
- округляетdouble
до целого числаavailableWidth / (px + margin)
- будет низким числом (доляavailableWidth
)
Поэтому вы собираетесь получить 0
иногда особенно на экранах меньшего размера и / или экранах меньшей плотности.
Имеет ли это смысл? Может быть, это не проблема, но я бы начал там. Трудно точно сказать вам проблему, не зная всего контекста, но это, вероятно, ваша проблема.
Если это не ваша проблема, не могли бы вы сказать, какова ваша ценность для availableWidth
, px
, а также margin
во время исполнения?