android set listview height dynamically

2019-02-10 10:42发布

问题:

i have ExpandableListview inside ScrollView and i know that's not good but i had too, the only solution to show the whole list is by set its height by code using layoutParams

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, ListViewData.length());

this solution is good but i can't figure the right height that i should give in the Params, SO is there a way to know the actual size from the size of the array

Edit: i came up with a solution that everytime i expand a group of the list am gonna change the height to fit with new geight

回答1:

try this, Use Child based on listview. setListViewHeightBasedOnChildren() this will set your listview child based height

 public class Utils {

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter(); 
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

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



}


回答2:

Your ListView is effectively unneeded in this case. You can as well loop over your adapter's items and just add them to a vertical LinearLayout inside your ScrollView.

In case you do not want to change a lot of code:

Replace ListView.setAdapter with

LinearLayout ll; //this should be the vertical LinearLayout that you substituted the listview with
for(int i=0;i<adapter.getCount();i++) {
    View v = adapter.getView(position, null, null);
    ll.addView(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
}

If you already use an OnItemClickListener add after View v = adapter.getView(position, null, null); the following

final int position = i;
v.setOnClickListener(new OnClickListener() {
    public onClick(View v) {
        yourOnItemClickListener.onItemClick(null, v, position, 0);
    }
});

In this case you do not have to worry about any miscalculation in the height.



回答3:

Try this, it works for my same problem

public static boolean setListViewHeightBasedOnItems(ListView listView) {

ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {

    int numberOfItems = listAdapter.getCount();

    // Get total height of all items.
    int totalItemsHeight = 0;
    for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
        View item = listAdapter.getView(itemPos, null, listView);
        item.measure(0, 0);
        totalItemsHeight += item.getMeasuredHeight();
    }

    // Get total height of all item dividers.
    int totalDividersHeight = listView.getDividerHeight() * 
            (numberOfItems - 1);

    // Set list height.
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalItemsHeight + totalDividersHeight;
    listView.setLayoutParams(params);
    listView.requestLayout();

    return true;

} else {
    return false;
}}

requestLayout() method is called on the view because something has changed that invalidated its layout - forces redrawing.



回答4:

you can set a variable in dimensions file for different screen sizes and then multiply it by the number of items of list you want to display.