Android: как измерить общую высоту ListView

Мне нужно измерить общую высоту ListView, но кажется, что я постоянно получаю неправильные значения. Я использую этот код:

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

    int totalHeight = 0;
    int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(),
            MeasureSpec.AT_MOST);
    Log.w("DESIRED WIDTH", String.valueOf(listAdapter.getCount()));
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
        totalHeight += listItem.getMeasuredHeight();
        Log.w("HEIGHT"+i, String.valueOf(totalHeight));
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}

Проблема в том, что я получаю больший рост, чем я должен получить. Каждый элемент списка измеряется по-разному, и все элементы имеют одинаковую высоту, поэтому он определенно не должен этого делать. Высота каждого элемента по крайней мере вдвое превышает реальную высоту.

Спасибо заранее.

edit1:

У меня есть два ListViews, и они оба имеют элементы с 6-7 полями EditText. Я показываю/скрываю ListView, если пользователь хочет записать/удалить значения в EditText. Все работает хорошо, за исключением случаев, когда я хочу показать список, он занимает много места, потому что метод вычисления ListView требует много места. Из-за этого у меня много свободного места ниже этого ListView. Как в три раза больше пустого пространства, которое необходимо.

Ответ 1

Наконец, я сделал это! Это рабочий код, который измеряет высоту ListView и устанавливает ListView в полном размере:

public static void getTotalHeightofListView(ListView listView) {

    ListAdapter mAdapter = listView.getAdapter();

    int totalHeight = 0;

    for (int i = 0; i < mAdapter.getCount(); i++) {
        View mView = mAdapter.getView(i, null, listView);

        mView.measure(
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),

                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

        totalHeight += mView.getMeasuredHeight();
        Log.w("HEIGHT" + i, String.valueOf(totalHeight));

    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (mAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();

}

Ответ 2

Попробуйте что-то вроде этого:

listItem.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

  public void onGlobalLayout() {
    int listItemHeight = listItem.getHeight();
  }
});

Если вы хотите высоту listView, попробуйте это:

listView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

  public void onGlobalLayout() {
    int listViewHeight = listView.getHeight();
  }
});

Вы также можете проверить это: Рассчитать размер представления списка или как его полностью раскрыть

Ответ 3

ListView кэширует элементы представления и повторно использует их. Если у вас есть просмотр списка с 1000 элементами и только 6 видимых, почему, это не стоит делать 994 не показывая.

Измерение всего ListView будет означать визуализацию каждого ListItem, кажется немного переборщиком.

Я не знаю, чего вы пытаетесь достичь, но, вероятно, лучший способ:)