Listview same height as content
Asked Answered
H

10

17

I used custom listview . Content comes from dynamic I want to same listview height same as content.

I used wrap_content but this does not help If I remove scrollview then its work

Code. "The vertically scrolling ScrollView should not contain another vertically scrolling widget (ListView)"

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background_img"
    android:scrollbars="none" >

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

<ListView
            android:id="@+id/lstsemtrack"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
        android:divider="#f2e4e4"
        android:dividerHeight="1dip"
             >
        </ListView>

Item list

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dip"
    android:scrollbars="none" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="4" >

        <TextView
            android:id="@+id/txtBiology"
            style="@style/sem_rowtext"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="5dip"
            android:layout_weight="1"
            android:text="Biology" />

        <TextView
            android:id="@+id/txtClass"
            style="@style/sem_rowtext"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Biology - 101" />

        <TextView
            android:id="@+id/txtGrade"
            style="@style/sem_rowtext"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Grade" />

        <TextView
            android:id="@+id/txtGrade"
            style="@style/sem_rowtext"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Remove" />
    </LinearLayout>

</LinearLayout>

output like below I want same as content no scrollview

enter image description here

Hansel answered 25/9, 2013 at 6:27 Comment(3)
Try giving the android:layout_height as match_parent and see if that helps.Maremma
It has no relation with the list view and the content of it. your layout is set up right. It's related to the parents of your list view.Sascha
possible duplicate of How can I put a ListView into a ScrollView without it collapsing?Argufy
A
43

Use this code

public class MyListView  extends ListView {

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

    public MyListView  (Context context) {
        super(context);
    }

    public MyListView  (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
Aude answered 12/6, 2014 at 14:11 Comment(2)
Saved me! also tested on 6.0Kentiggerma
One drawback of such implementation is that it has artifacts with async loading of images for items (images are duplicated or have wrong positions).Declamatory
G
12

You shouldn't put a ListView inside a ScrollView because ListView itself is a view group that displays a list of scrollable items. If you use it inside scrollview it will not receive scroll events because they all are handled by the parent ScrollView. Using a ListView to make it not scroll is extremely expensive and goes against the whole purpose of ListView. You should NOT do this. Just use a LinearLayout instead.

However, if you really want to do this you can have a look at this: How can I put a ListView into a ScrollView without it collapsing?

Germangermana answered 25/9, 2013 at 7:24 Comment(1)
Thank you for your comment! It made me realize how wrong I was trying to use a ListView to show always the same data, with no scroll (inside a ScrollView, too)! Using LinearLayout now.Vexed
L
8

In your parent layout set the height to wrap_content. This should work.

Lamont answered 25/9, 2013 at 6:43 Comment(2)
Thanks, I've been looking for a solution for 4 hours :)Sigismundo
@paddydub: I'm glad that my answer helped you.Lamont
P
4

Other suggestions will not work, because there is no way to determine the height of the content of the ListView until after it's drawn into the screen (unless of course you have a fixed height, then use that as your ListView's height also).

What you can do is set the ListView's height AFTER drawing the elements inside it. You can do this in onWindowFocusChanged in your activity. As an example:

public void onWindowFocusChanged(boolean hasFocus) {
    // get content height
    int contentHeight = listView.getChildAt(0).getHeight();

    // set listview height
    LayoutParams lp = listView.getLayoutParams();
    lp.height = contentHeight;
    listView.setLayoutParams(lp);
}
Pyrostat answered 25/9, 2013 at 6:52 Comment(0)
N
2

Use Own Custom ListView
Create a class CustomListView.java and extend ListView like this..

public class CustomListView extends ListView {

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

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

@Override
protected void onDraw(Canvas canvas)
{
    if (getCount() != prevCount) 
    {
        int height = getChildAt(0).getHeight() + 1 ;
        prevCount = getCount();
        params = getLayoutParams();
        params.height = getCount() * height;
        setLayoutParams(params);
    }

    super.onDraw(canvas);
}

}

Then use it in xml

 <yourPackageName.CustomListView
        android:id="@+id/lstsemtrack"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#f2e4e4"
        android:dividerHeight="1dip">
 </yourPackageName.ListView>
Northington answered 29/1, 2017 at 5:21 Comment(0)
A
2

As noted by Permita you should not have a ListView in a Scrollview. You should use for example a LinearLayout instead.

In some cases you have already made custom adapters you want to reuse. In that case these code snippets may be useful.

Old view:

...
<ListView android:id="@+id/myListView" ... />
...

New view:

...
<LinearLayout
    android:orientation="vertical"
    android:id="@+id/myLinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
...

Old code: (in dialog/fragment/activity)

YourAdapter listAdapter;
...
ListView listView = (ListView)rootView.findViewById(R.id.myListView);
...
if (listView != null) {
    if (listAdapter == null) {
        listAdapter = new YourAdapter(...);
        listView.setAdapter(listAdapter);
    } else {
        listAdapter.notifyDataSetChanged();
    }
}

New code: (doing some "listview"-stuff ourselves, to reuse views if possible)

YourAdapter listAdapter;
...
LinearLayout linearLayout = (LinearLayout) rootView.findViewById(R.id.myLinearLayout);
...
if (linearLayout != null) {
    if (listAdapter == null) listAdapter = new YourAdapter(...);
    for (int pos = 0; pos < listAdapter.getCount(); pos++) {
        View existingView = linearLayout.getChildAt(pos);
        if (existingView != null) listAdapter.getView(pos, existingView, linearLayout);
        else linearLayout.addView(listAdapter.getView(pos, null, linearLayout));
    }
    while (linearLayout.getChildCount() > listAdapter.getCount()) linearLayout.removeViewAt(listAdapter.getCount());
}

UPDATE: Or just add this to your adapter and call it instead of setAdapter on the list view and and notifyDataUpdated on the adapter:

public void updateOnLinearView(ViewGroup parentView) {
    // Note reusing child views if there are any
    for (int pos = 0; pos < getCount(); pos++) {
        View existingView = parentView.getChildAt(pos);
        if (existingView != null) getView(pos, existingView, parentView);
        else parentView.addView(getView(pos, null, parentView));
    }
    while (parentView.getChildCount() > getCount())
        parentView.removeViewAt(getCount());
}
Aubrey answered 23/2, 2018 at 20:56 Comment(0)
H
1

couple of things to note here..

  1. Do not use ListView inside the ScrollView
  2. You will need to dynamically calculate the listView items to get the height for it.

Here is a function to do that..

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

    int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        if (listItem instanceof ViewGroup)
            listItem.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

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

}

You will need to call the same in

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
setListViewHeightBasedOnChildren(listview)
    }
Haematoid answered 10/10, 2019 at 6:55 Comment(0)
M
0

try wrapping your list view with a LinearLayout and set the LinearLayout's height to wrap_content.

Marinmarina answered 25/9, 2013 at 6:36 Comment(0)
F
0

The problem is the "ListView" inside "ScrollView"

ListView have already an automatic scroll, so you can delete it

Fusco answered 14/12, 2020 at 18:55 Comment(0)
E
-1

Use android:layout_height="match_parent", it will work I think.

Exsiccate answered 25/9, 2013 at 6:31 Comment(2)
Which parent layout do you used?Exsiccate
I got The vertically scrolling ScrollView should not contain another vertically scrolling widget (ListView)Hansel

© 2022 - 2024 — McMap. All rights reserved.