Подтвердить что ты не робот

Как получить высоту элемента в разделе "Пересмотр" в "onBindViewHolder"

Высота элемента RecyclerView не фиксирована, мне нужно установить фоновое изображение для каждого элемента, поэтому я хочу получить высоту элемента recyclerView для изменения размера изображения, но itemView.getHeight() всегда возвращает 0 в onBindViewHolder.

Я пытался найти много вопросов или статей, но я все еще не могу получить хорошее решение.

4b9b3361

Ответ 1

Короткие

Измерьте представление вручную

view.measure(
             View.MeasureSpec.makeMeasureSpec(recyclerViewWidth, View.MeasureSpec.EXACTLY),
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

и получить высоту с помощью view.getMeasuredHeight()

Фон

Вид вернет действительное значение для View.getHeight() только после его измерения. Само измерение автоматически произойдет системой, когда представление будет отображаться на экране.

Когда Android хочет отобразить макет, он будет рекурсивно вызывать функцию view.layout() для каждого вида в дереве представлений. Каждый родитель сообщает своим детям ограничения, которые они могут иметь (ширина/высота), и спрашивать их сами view.measure(). В результате в представлении будут сохранены измеренные значения BASED на ограничениях в назначенных членах (MeasuredHeight/Width). Обратите внимание, что в этот момент view.getMeasuredHeight() будет удерживать значение, а View.getHeight() по-прежнему будет недействительным. View.getHeight() возвращает только действительное значение, если представление имеет фактическую высоту в иерархии пользовательского интерфейса.

Резюме

Итак, чтобы узнать высоту элемента вида, прежде чем он будет измерен и выложен системой, нам нужно будет вручную вызвать функцию view.measure().

Функция измерения ожидает 2 параметра, которые получены из представления LayoutParams + родительских ограничений.

В приведенном выше примере кода мы измеряем представление, заставляющее его ширину ТОЧНО ширину родительского элемента (RecycleView), а высота не ограничена.

Ответ 2

Я предлагаю вам определить несколько файлов макетов с ожидаемой высотой и накачать их в соответствии с некоторыми критериями в наборе данных.

ViewHolder onCreateViewHolder (ViewGroup parent, int viewType){
  if(some condition){
    //inflate layout 1
  }else{
    //inflate layout 2
 }

или как ответили здесь: вы можете получить измерения при инициализации держателя вида

itemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = itemView.getMeasuredWidth();
int height = itemView.getMeasuredHeight();

Ответ 3

Как насчет этого:

view.post(() -> {
   int width = view.getMeasuredWidth();
   int height = view.getMeasuredHeight();
}

Ответ 4

используя этот код, чтобы получить высоту объекта просмотра переработчика:

view.getViewTreeObserver().addOnGlobalLayoutListener(new 
         ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //don't forget remove this listener
        view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        //get item height here
        int itemHeight = v.getHeight();
    }
});

Ответ 5

MyViewHolder.kt

С помощью метода addOnGlobalLayoutListener() значение высоты получается до отрисовки TextView. А затем сохраните его в переменной-члене.

Ключ заключается в том, чтобы изменить пользовательский интерфейс внутри и снаружи реализации слушателя, чтобы не было проблем с рендерингом (когда перерисовываются представления).

То есть вы должны использовать геттер внутри слушателя и; сеттер внутри и снаружи слушателя.

companion object {

    var maxHeight: Int = 0

    fun create(mContext: Context): MyViewHolder {
        val view = LayoutInflater.from(mContext).inflate(R.layout.item_answer, null)

        updateLayout(view)

        view.viewTreeObserver.addOnGlobalLayoutListener {

            if (view.myTextView.height > maxHeight)
                maxHeight = view.myTextView.height

            updateLayout(view)

        }

        return MyViewHolder(mContext, view).apply {
            setIsRecyclable(false)
        }
    }

    fun updateLayout(view: View) {
        if (maxHeight != 0 && view.myTextView.height != maxHeight) 
            view.myTextView.height = maxHeight
    }


}

GL

Источник