Как настроить ListView для автоматического изменения его высоты? - PullRequest
4 голосов
/ 28 июля 2010

У меня три ListView виджета в одном LinearLayout.Примерно так (я опускаю элементы XML, которые не относятся к этому примеру):

<LinearLayout>
    <ListView
      android:layout_width="fill_parent"
      android:layout_height="360dp"/>
    <ListView
      android:layout_width="fill_parent"
      android:layout_height="360dp"/>
    <ListView
      android:layout_width="fill_parent"
      android:layout_height="360dp"/>
</LinearLayout>

Это заставляет список иметь высоту 360 градусов.Конечно, это будет его высота, даже если в списке мало пунктов.Итак, мой вопрос: как сделать так, чтобы списки имели автоматическую высоту?Я хочу, чтобы высота ListView принимала точный размер суммы всех элементов списка.

Ответы [ 5 ]

8 голосов
/ 29 июля 2010

Я реализовал это следующим образом (код находится в стадии разработки, поэтому это скорее источник идеи, чем решение):

package com.customcontrols;
public class NoScrollListView extends ListView
{
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0) );

        // here I assume that height's being calculated for one-child only, seen it in ListView's source which is actually a bad idea
        int childHeight = getMeasuredHeight() - (getListPaddingTop() + getListPaddingBottom() +  getVerticalFadingEdgeLength() * 2);

        int fullHeight = getListPaddingTop() + getListPaddingBottom() + childHeight*(getCount());

        setMeasuredDimension(getMeasuredWidth(), fullHeight);
    }
}

расчет не идеален, но он близок и работает до сих пор.после этого вы просто создаете макет, подобный следующему:

ScrollView com.customcontrol.NoScrollListView com.customcontrol.NoScrollListView com.customcontrol.NoScrollListView / ScrollView

ScrollView очень важен, так как вы легко можете выйти изграницы экрана.

PS.Вычисление осуществляется на основе прямой кишки, поскольку большинство методов вычисления в ListView & Co являются пакетными, что является довольно странным выбором для общедоступных классов для пользовательского интерфейса.

3 голосов
/ 25 февраля 2015

Я нашел решение на установить ListView Высота на основе детей , эта работа

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter(); 
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}
3 голосов
/ 19 января 2011

Вместо того, чтобы редактировать мой предыдущий ответ, вот моя актуальная версия (после того, как дело, наконец, стало проблемой, и мне пришлось ее исправить)

    @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0));

    int childHeight = getMeasuredHeight() - (getListPaddingTop() + getListPaddingBottom() +  getVerticalFadingEdgeLength() * 2);

    // on a first run let's have a space for at least one child so it'll trigger remeasurement
    int fullHeight = getListPaddingTop() + getListPaddingBottom() + childHeight*(getCount());

    int newChildHeight = 0;
    for (int x = 0; x<getChildCount(); x++ ){
        View childAt = getChildAt(x);

        if (childAt != null) {
            int height = childAt.getHeight();
            newChildHeight += height;
        }
    }

    //on a second run with actual items - use proper size
    if (newChildHeight != 0)
        fullHeight = getListPaddingTop() + getListPaddingBottom() + newChildHeight;

    setMeasuredDimension(getMeasuredWidth(), fullHeight);
}

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

1 голос
/ 26 июля 2016

попробуйте это ... список посмотреть реальную высоту

просмотр списка в формате xml

<ListView
 android:id="@+id/my_listview"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

просмотр списка Java-кодирования

    ListView lView = (ListView)findViewById(R.id.my_listview);
    lView.setAdapter(adapter);
    setListViewHeightBasedOnChildren(lView);

setListViewHeightBasedOnChildren метод

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}
1 голос
/ 28 июля 2010

Вы можете попробовать выполнить итерацию по строкам ListView (см. Методы на ViewGroup), найти их высоты, суммировать их и изменить ListView высоту.

При этом я полностью ожидаю, что это будет ужасно:

  • Вам необходимо учитывать размер экрана, чтобы ваши списки не выходили за границы экрана
  • Необходимо учитывать изменения ориентации
  • Вам необходимо принять во внимание любые изменения ваших данных (например, удаление строк может потребовать сокращения вашего списка)
  • Etc.

Если ваша цель в действительности состоит в том, чтобы иметь один список, но у вас есть три источника данных, объедините данные и поместите их в один список. Мой MergeAdapter может помочь здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...