简体   繁体   中英

Listview Height issue inside ScrollView in Android

I am using ListView inside ScrollView in Android. So, as we all know, It will occur height issue. For that, I am setting ListView size using below code :

public static void getListViewSize(ListView myListView, Context context) {
        ListAdapter myListAdapter = myListView.getAdapter();

        if (myListAdapter == null) {
            return;
        }

        int totalHeight = 0;
        for (int size = 0; size < myListAdapter.getCount(); size++) {

            View listItem = myListAdapter.getView(size, null, myListView);
            if (listItem instanceof ViewGroup)
                listItem.setLayoutParams(new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.WRAP_CONTENT,
                        RelativeLayout.LayoutParams.WRAP_CONTENT));

            WindowManager wm = (WindowManager) context
                    .getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            @SuppressWarnings("deprecation")
            int screenWidth = display.getWidth();
            int listViewWidth = screenWidth - 65;
            int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth,
                    MeasureSpec.AT_MOST);
            listItem.measure(widthSpec, 0);

            totalHeight += listItem.getMeasuredHeight();
        }

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

Xml :

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/white" >

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

        <ListView
            android:id="@+id/lvHomeStream"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            android:divider="#b5b5b5"
            android:dividerHeight="1dp" >
        </ListView>

        <TextView
            android:id="@+id/tvMoreRecords"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="15dp"
            android:layout_marginTop="10dp"
            android:background="@drawable/list"
            android:gravity="center"
            android:paddingBottom="5dp"
            android:paddingTop="5dp"
            android:text="@string/viewmore"
            android:textColor="@color/blue"
            android:textSize="16sp" />
    </LinearLayout>

</ScrollView>

It works fine if height of each ListView item is same. But, if height of each ListView item is unusual, then it leave extra big space between ListView end boundary and TextView .

Please help me to solve this issue.

ok i share my project code here may be it helps you..

This class calculate the height and automatically adjust the layoutparams.

Solution:-

 package com.kview;

 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.GridView;
 import android.widget.ListView;

 public class FullLengthListView extends ListView {

boolean expanded = true;

public FullLengthListView(Context context, AttributeSet attrs,
        int defaultStyle) {
    super(context, attrs, defaultStyle);
}

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

public boolean isExpanded() {
    return expanded;
}

public void setExpanded(boolean expanded) {
    this.expanded = expanded;
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // HACK! TAKE THAT ANDROID!
    if (isExpanded()) {
        // Calculate entire height by providing a very large height hint.
        // View.MEASURED_SIZE_MASK represents the largest height possible.
        int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

        android.view.ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    } else {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
  }

This is not a good practice to put a listview in scrollView.and if put the listview inside the scroll then the height of the listview is a measure issue. you have to fix the height of listview.and to scroll both listview and scroll view your have to set the touch listner on listview,like:

listview.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            v.getParent().requestDisallowInterceptTouchEvent(true);
            return false;
        }
    });

now,when you touch the listview,it will disable the scroll of scroll view and your listview will work.else when you touch on other part of screen then scroll view will work smoothly.only this the possible solution.

Update

now your an use recyclerview, since 23.0.2 support lib, it supports wrap_content height too.

It is the best answer to your question and it is provided by Romain Guy . (he is the father of ListView)

How can I put a ListView into a ScrollView without it collapsing?

You should use a LinearLayout instead of your ListView . Something like this:

public class MyListLayout extends LinearLayout implements
        View.OnClickListener {

    private Adapter list;
    private View.OnClickListener mListener;

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

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

    }

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

    @Override
    public void onClick(View v) {
        if (mListener!=null)
            mListener.onClick(v);
    }

    public void setList(Adapter list) {
        this.list = list;

        //Popolute list
        if (this.list!=null){
            for (int i=0;i<this.list.getCount();i++){
                View item= list.getView(i, null,null);
                this.addView(item);
            }
        }

    }

    public void setmListener(View.OnClickListener mListener) {
        this.mListener = mListener;
    }
}

As Dev Carlsberg suggested DONT USE ListView inside ScrollView you can change the xml to this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/background_light" >

    <TextView
        android:id="@+id/tvMoreRecords"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="15dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/list"
        android:gravity="center"
        android:paddingBottom="5dp"
        android:paddingTop="5dp"
        android:text="@string/viewmore"
        android:textColor="@color/blue"
        android:textSize="16sp" />

    <ListView
        android:id="@+id/lvHomeStream"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:divider="#b5b5b5"
        android:dividerHeight="1dp" >
    </ListView>

</RelativeLayout>

or alternatively you may find the

Android ListView with Load More Button

Android - ListView to load more items when reached end

Hope it helps :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM