动态设置Android中ListView的高度

6
我在ScrollView中使用了ExpandableListview,虽然这样做不好,但我必须这么做。唯一的解决方法是通过代码设置其高度,使用layoutParams才能显示整个列表。

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

这个解决方案很好,但我无法找到应该在Params中给出的正确高度,是否有一种方法可以从数组的大小中知道实际大小? 编辑: 我想到了一个解决方案,每次展开列表组时,我将改变高度以适应新的高度。

嘿,你会写出你的解决方案吗? - yshrsmz
4个回答

16

尝试使用基于列表视图的子项。 setListViewHeightBasedOnChildren() 这将设置您的列表视图子项的高度。

 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();
}



}

好的,我现在会尝试它。 - alaa7731
1
它可以工作,但你应该添加这些解决方案的来源。 - Kailas
@Murali Ganesan 我想在GridView中使用上面的代码,需要替换哪些代码才能获取Grideview的DividerHeight()。谢谢 - Ashish Shukla
当调用listView.setLayoutParams(params)时,已经调用了listView.requestLayout(),因此应将其删除。 - Alex Loper
我必须说这是一个干净的逻辑,大部分时间它都能正常工作。但是很少情况下,它设置的高度比应该设置的高度要高得多。不知道为什么,但是这段代码在某些情况下存在一些缺陷。 - srv242

10

在这种情况下,您的ListView实际上是不需要的。 您可以循环遍历适配器的项目,并将它们添加到滚动视图内的垂直LinearLayout中。

如果您不想更改大量代码:

请使用ListView.setAdapter替换

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);
}

如果您已经使用了OnItemClickListener,请在View v = adapter.getView(position, null, null);之后添加以下内容:

final int position = i;
v.setOnClickListener(new OnClickListener() {
    public onClick(View v) {
        yourOnItemClickListener.onItemClick(null, v, position, 0);
    }
});
在这种情况下,您无需担心高度上的任何错误计算。

我曾经为ListView想出了这个解决方案,但现在它将改为ExpandableListView :/ ,所以在这种情况下也必须动态完成。 - alaa7731
我认为你应该针对这个编辑创建一个新问题。你特别要求了一个列表视图。 - Sherif elKhatib
1
只返回翻译后的文本内容:和来自黎巴嫩的问候(: - Sherif elKhatib
这是最终更好的解决方案。在每种情况下,通过黑客手段来操作ListView并不能很好地处理行中可能包含的各种元素,例如动态多行TextView或子ListView - Cord Rehn

4

尝试这个方法,对于我遇到的同样问题有效。

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()方法被调用在视图上,因为有些事情发生导致其布局无效 - 强制重绘。


item.measure(0, 0); 处抛出了 NPE。 - SilentKnight

0

你可以在尺寸文件中设置一个变量,针对不同的屏幕尺寸,然后将其乘以你想要显示的列表项数目。


我尝试使用一个固定变量,然后将其乘以物品数量,但在不同的屏幕尺寸上它无法正常工作。 - alaa7731
@alaa7731 这就是我说的,你需要为不同的屏幕尺寸设置不同的值。 - PrincessLeiha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接