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

Сделать последний элемент /ViewHolder в RecyclerView заполнить остальную часть экрана или иметь минимальную высоту

Я борюсь с RecyclerView. Я использую просмотр recycler для отображения деталей моего класса модели.

//My model class
MyModel {
    String name;
    Double latitude;
    Double longitude;
    Boolean isOnline;
    ...
}

Так как некоторые из значений могут отсутствовать, я использую RecyclerView с настраиваемыми типами представлений (один из которых представляет каждое значение моей модели).

//Inside my custom adapter
public void setModel(T model) {
    //Reset values
    itemCount = 0;
    deviceOfflineViewPosition = -1;
    mapViewPosition = -1;

    //If device is offline, add device offline item
    if (device.isOnline() == null || !device.isOnline()) {
        deviceOfflineViewPosition = itemCount;
        itemCount++;
    }

    //Add additional items if necessary
    ...

    //Always add the map as the last item
    mapViewPosition = itemCount;
    itemCount++;

    notifyDataSetChanged();
}

@Override
public int getItemViewType(int position) {
    if (position == deviceOfflineViewPosition) {
        return ITEM_VIEW_TYPE_OFFLINE;
    } else if (position == mapViewPosition) {
        return ITEM_VIEW_TYPE_MAP;
    } else if (...) {
        //Check for other view types
    }
}

С RecyclerView я могу легко определить во время выполнения, какие значения доступны и добавить соответствующие элементы в источник данных RecyclerView. Я просто использовал код, но моя модель имеет гораздо больше значений, и у меня есть намного больше типов просмотров.

Последний элемент в RecyclerView всегда является картой и всегда присутствует. Даже если в моей модели нет никакой ценности, по крайней мере будет один элемент, карта.

ПРОБЛЕМА. Как я могу сделать последний элемент в RecyclerView заполнить оставшееся пространство на экране, а также получить минимальное значение. Размер должен быть тем, что когда-либо стоило: оставшееся пространство или минимальная высота. Например:

  • Модель имеет несколько значений, которые в сумме занимают 100dp экрана 600dp → высота карты должна быть 500dp
  • Модель имеет множество значений, которые в сумме занимают 500dp экрана 600dp → map heigh должно быть минимальным значением 200dp
  • Модель не имеет значений → карта заполняет весь экран

введите описание изображения здесь

4b9b3361

Ответ 1

Вы можете найти оставшееся пространство в RecyclerView после размещения последнего элемента и добавить это оставшееся пространство к minHeight последнего элемента.

val isLastItem = getItemCount() - 1 == position
if (isLastItem) {
            lastItemView.doOnLayout {
                val recyclerViewHeight = recyclerView.height
                val lastItemBottom = lastItemView.bottom
                val heightDifference = recyclerViewHeight - lastItemBottom
                if (heightDifference > 0) {
                    lastItemView.minimumHeight = lastItemView.height + heightDifference
                }
            }
        }

В onBindHolder проверьте, является ли элемент последним, используя getItemCount() - 1 == position. Если это последний элемент, найдите разницу высот, вычтя высоту recyclerView с последним дном lastItem (getBottom() дает вам самый нижний пиксель представления относительно его родителя. В этом случае нашим родителем является RecyclerView).

Примечание. Этот код является Kotlin, а функция doOnLayout из Android KTx. Также ваша высота RecyclerView должна быть match_parent чтобы это работало (я думаю, это очевидно).

Если разница больше 0, добавьте ее к текущей высоте последнего вида и установите ее как minHeight. Мы устанавливаем это как minHeight вместо того, чтобы устанавливать непосредственно как height чтобы поддерживать динамическое изменение содержимого для последнего представления.