10

I need to find the height of android ListView with custom ListVAdapter. Each of ListView items can be of varying height. I have tried the following code which I found here:

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, MeasureSpec.UNSPECIFIED);
            totalHeight += listItem.getMeasuredHeight();
        }

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

But it doesn't give actual height; it gives same height for all list items. Is it possible to find ListView height with list items of varying height?

RobinHood
  • 10,897
  • 4
  • 48
  • 97
althaf_tvm
  • 773
  • 3
  • 15
  • 28
  • 3
    For what do you need the `ListView`'s height? – user Dec 11 '12 at 06:23
  • I am using ListView to show set of comments from users in my view. The view has both collapsed and expanded view of comments, so need the listviews height to show it in expanded state in order to show all the comments. I know there is addFooter() and addHeader() for ListView so that the whole view becomes scrollable (which I am currently using); but is there a way I can get the list's height? – althaf_tvm Dec 11 '12 at 08:38
  • 1
    If I understood your comment you need the full `ListView`'s height so you can assign that to the `ListView` and show all its rows. If this is what you're trying to do, then you could simply "replicate" the `ListView` by inflating its row layout for all the items in the adapter(instead of getting its complete height). In the end you shouldn't do this because you'll ignore the purpose of the `ListView`, to recycle views for performance and you can get in trouble. – user Jan 07 '13 at 11:20
  • Can you post your list item layout xml? I just tried your code with list items of varying height and actually got different heights from `listItem.getMeasuredHeight()`. – Matthias Robbers Jan 07 '13 at 15:55
  • There is no any problem to do what you want. Your code iterates over all listview's childrens, measures them and summs up overall listview height. Before run your code you should set your adapter with comments data. I dont like this line: listItem.measure(0, MeasureSpec.UNSPECIFIED); You should set first parameter to listview's actual width to measure listItem height correctly. – Leonidos Jan 07 '13 at 18:08
  • @matthias: This is my list item layout – althaf_tvm Jan 09 '13 at 04:50
  • You don't need to know height of ListView just make ListView android:layout_height="match_parent" in layout and then. Add all items above ListView in header layout and all items below ListView in footer layout. Related [answer](http://stackoverflow.com/questions/13241294/how-to-make-a-lot-views-scroll-together-as-a-single-element-in-android/13241620#13241620). – Artyom Kiriliyk Jan 09 '13 at 20:30
  • @ArtyomKiriliyk : I am currently using header and footer with list view. But if listview's height is available it will be more convenient – althaf_tvm Jan 10 '13 at 09:50
  • @althaf_tvm: Of course this is available, but this is a bad practice. I've added the answer. – Artyom Kiriliyk Jan 10 '13 at 20:09

4 Answers4

15
private int getTotalHeightofListView() {

    ListAdapter LvAdapter = lv.getAdapter();
    int listviewElementsheight = 0;
    for (int i = 0; i < mAdapter.getCount(); i++) {
        View mView = mAdapter.getView(i, null, lv);
        mView.measure(
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        listviewElementsheight += mView.getMeasuredHeight();
    }
    return listviewElementsheight;
}

try this code.

jeevamuthu
  • 2,054
  • 4
  • 19
  • 33
2

When you call measure(0, MeasureSpec.UNSPECIFIED), you're telling the view layout system to use an infinite width, so for example TextViews may just flow to a single line. Try passing the width of your list view:

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter(); 
    int totalHeight = 0;
    int listWidth = listView.getMeasuredWidth();
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(
            MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        totalHeight += listItem.getMeasuredHeight();
    }
    // ...update list height
} 

You also need to be sure you call this after onMeasure has been called on the list view, or listView.getMeasuredWidth() will return 0.

Christopher Pickslay
  • 17,523
  • 6
  • 79
  • 92
1

You can use getHeight():

System.out.println("height of list view..."+listview.getHeight());

Or follow this answer.

Community
  • 1
  • 1
Artyom Kiriliyk
  • 2,513
  • 1
  • 17
  • 21
1

Based on @jeevamuthu code.

public static int getLVHeight(ListView listView) {
    ListAdapter adapter = listView.getAdapter();
    int height = 0;
    int count = adapter.getCount();
    for (int i = 0; i < count; i++) {
        View view = adapter.getView(i, null, listView);
        view.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        height += view.getMeasuredHeight();
    }
    height += listView.getDividerHeight() * (count - 1);
    return height;
}
CoolMind
  • 26,736
  • 15
  • 188
  • 224