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

Nick
  • 351
  • 3
  • 7
  • 22
  • Try giving the android:layout_height as match_parent and see if that helps. – S.A.Norton Stanley Sep 25 '13 at 06:30
  • 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. – hasan Sep 25 '13 at 06:33
  • possible duplicate of [How can I put a ListView into a ScrollView without it collapsing?](http://stackoverflow.com/questions/3495890/how-can-i-put-a-listview-into-a-scrollview-without-it-collapsing) – Lennart Sep 25 '13 at 07:38

10 Answers10

44

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);
    }
}
Sergey Shustikov
  • 15,377
  • 12
  • 67
  • 119
Raj008
  • 3,539
  • 2
  • 28
  • 26
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?

Community
  • 1
  • 1
Permita
  • 5,503
  • 1
  • 16
  • 21
  • 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. – danguilherme May 01 '16 at 17:41
8

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

VikramV
  • 1,111
  • 2
  • 13
  • 31
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);
}
Allan Pereira
  • 2,572
  • 4
  • 21
  • 28
josephus
  • 8,284
  • 1
  • 37
  • 57
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>
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());
}
Erik Melkersson
  • 899
  • 8
  • 19
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)
    }
Smaran
  • 1,651
  • 2
  • 11
  • 15
0

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

Gil Moshayof
  • 16,633
  • 4
  • 47
  • 58
0

The problem is the "ListView" inside "ScrollView"

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

-2

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

Pratik Dasa
  • 7,439
  • 4
  • 30
  • 44