Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate the size of a list view or how to tell it to fully expand

Tags:

android

I am currently trying to use a ListView inside of a ScrollView. I know from what I've read that this is looked down upon, but I'm trying to get the ListView to expand completely by showing all of its rows so there is no need for it to scroll. I've been struggling, however, with how to tell the ListView to completely expand to show all of its rows since it needs a defined height. How do I calculate the height of a fully expanded ListView before it is drawn?

This problem mainly stems from the fact that you can't put a scrollable view inside of another scrollable view. I am okay with the fact that the ListView won't be able to scroll as long as I can make it expand to show all of its rows. I cannot do this, however, without being able to give it a defined height, which it seems I would need to calculate.

My full layout is too big for the "physical" screen and needs to scroll in order to show the rest of the list and buttons at the bottom. I'm trying to get across that the "virtual" screen is too big to fit on one screen even without the ListView there.

like image 892
Rudy Mutter Avatar asked Feb 22 '10 17:02

Rudy Mutter


4 Answers

Well, thanks to Rudy, his suggestions was very helpful. Here is how it can be implemented.

1) Create a new class that extends ListView:

package com.example.android.views;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ListView;

public class ExpandedListView extends ListView {

    private android.view.ViewGroup.LayoutParams params;
    private int old_count = 0;

    public ExpandedListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getCount() != old_count) {
            old_count = getCount();
            params = getLayoutParams();
            params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0);
            setLayoutParams(params);
        }

        super.onDraw(canvas);
    }

}

2) ... and finally add the new view to your xml layout file:

<com.example.android.views.ExpandedListView
    android:id="@+id/list"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scrollbars="none"
    android:padding="0px"
    />
like image 146
netzpurist Avatar answered Oct 17 '22 00:10

netzpurist


The correct way to calculate the height is precisely:

int height = 0;
for (int i = 0; i < listView.getChildCount(); i++) {
    height += listView.getChildAt(i).getMeasuredHeight();
    height += listView.getDividerHeight();
}
like image 41
Romain Piel Avatar answered Oct 17 '22 01:10

Romain Piel


Attention! Correct way to calculate height is not

params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0);

We have to add height of each (minus one) divider heights.

if(oldCount > 0 && getCount() > 0)
    params.height = getCount()
                  * (getChildAt(0).getHeight() + getDividerHeight())
                  - getDividerHeight();
else
    params.height = 0;
like image 11
alcsan Avatar answered Oct 17 '22 01:10

alcsan


@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    if (this.isExpanded) {
        final int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
        final ViewGroup.LayoutParams params = this.getLayoutParams();
        params.height = this.getMeasuredHeight();
    } else {
       super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
like image 4
dfritsi Avatar answered Oct 17 '22 02:10

dfritsi