Android: How to measure total height of ListView-ThrowExceptions

Exception or error:

I need to measure total height of the ListView but it seems I’m constantly getting wrong values. I’m using this code:

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();
}

Problem is that I’m receiving larger height than I should receive. Every list item is measured differently and all items have the same height so it definitely shouldn’t do that. Height of each element is at least double of it’s real height.

Thank you in advance.

edit1:

I have two ListViews and they both have items with 6-7 EditText fields. I show/hide ListView if user wants to write/delete values in EditText. Everything works well except when I want to show list, it takes a lot of space because method calculated ListView needs a lot of space. Because of that I have a lot of empty space below that ListView. Like three times more empty space that needed.

How to solve:

Finally I’ve done it! This is the working code which measures ListView height and sets ListView in full size:

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();

}

###

Try something like this :

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

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

If you want the height of the listView then try this :

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

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

You could also check this : Calculate the size of a list view or how to tell it to fully expand

###

ListView caches the view items and reuses them. If you have a list view with 1000 items and only 6 visible, why, it’s not worth rendering the 994 not showing.

Measuring the whole ListView would mean render every ListItem, seems a bit overkill.

I don’t know what you are trying to achieve but there’s probably a better way 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *