Вызвать 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 ).

Есть идеи?

При проверке кода кажется, что ваш RecyclerView самом деле может быть getSpanSizeFromScreenWidth , но вашей логики в 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 во время выполнения?

  • Android Data Binding не работает с делегацией класса Kotlin
  • Как использовать привязку данных и Kotlin в Android Studio 3.0.0
  • метод getter бросает StackOverflowError
  • Использование lambda в пользовательском BindingAdapter с использованием Android Databinding и Kotlin
  • ошибка в передаче данных в андроид
  • Ошибка DataBinding в android Spinner
  • Использование LiveData с привязкой данных
  • Ошибка: выполнение выполнено для задачи ': app: kaptDemoTestingDebugKotlin'
  • Значение ObservableField не распространяется
  • Smartcasting на и с платформы типа в kotlin
  • Связывание данных: ObservableField со значением лямбда не компилируется
  • Interesting Posts

    Почему диапазон повторного использования Dagger медленнее, чем Singleton?

    Несоответствие типа JVM Kotlin в InteliJ

    Есть ли способ отфильтровать null Any? ценностей на карте Котлина?

    Издевательские общие интерфейсы с Kotlin и Mockito

    Повторная установка + повтор RxJava с другой ссылкой

    Кнопка Android Kotlin + диалог + список + список

    Как конвертировать этот код из iOS swift в Android Kotlin

    Единичное тестирование сопрограммы Kotlin с задержкой

    Создание экземпляра массива в Котлине

    rxAndroidBle получить длинный ответ записи

    Невозможно однозначно идентифицировать макет при добавлении вложенных фрагментов с помощью фрагментации

    Нельзя ли градировать проект построения, когда я добавляю класс ChatInformation kotlin, который расширяет RealmObject до моего проекта, где ошибка?

    Как перебирать иерархию классов?

    Android Kotlin меняет свой массив на spinner на карту

    Kapt3: java.io.File не может быть добавлен в java.lang.String

    Давайте будем гением компьютера.