Android Listview 测量高度 [英] Android Listview Measure Height

查看:22
本文介绍了Android Listview 测量高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到一种方法来根据其子项的高度设置列表视图的高度.我遵循了这里给出的解决方案:如何将 ListView 放入ScrollView 没有折叠?

I'm trying to find a way to set the height of a listview based on the height of its children items. I followed the solution given here: How can I put a ListView into a ScrollView without it collapsing?

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

        if(listItem != null){
            listItem.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));                
            listItem.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            //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();
}

现在我像这样在列表视图上调用上面的函数:

Now I call the above function on the listview like this:

public void displayReviews(ArrayList<Reviews> resultReviews){
    // Hide the loading progress
    hideReviewsLoading();

    if(resultReviews != null && resultReviews.size() > 0){
        mCurrentReviewList.onFetchFinished(resultReviews);
        setListViewHeightBasedOnChildren(mCurrentReviewList.getListView());
    }
    else{
        // Display a generic text to indicate no reviews are in yet
        displayEmptyText();
    }
}

mCurrentreviewList 上方是一个 ListFragment,它基本上有一个适配器来设置布局中的元素.

Here above the mCurrentreviewList is a ListFragment which basically has an adapter to set the elements within a layout.

我遇到的问题是它测量的每个列表项的高度不准确.因此,最终当所有列表项(评论)都填充到包含它的整个列表视图时,永远不会完全显示所有列表项.它在下方某处切断 - Like 仅显示 10 条评论中的 7.5 条评论.

The problem I'm having is that the height of each listitem that it measures is not accurate. And so in the end when all the list items(reviews) are populated the overall listview that contains it, never fully displays all the list items. It cuts off somewhere below - Like only shows 7.5 reviews out of a 10 total.

我不确定我做错了什么.任何帮助和指导将不胜感激!

I'm not sure what I'm doing incorrectly. Any help and direction would be greatly appreciated!

推荐答案

好的,我似乎能够找出测量不准确的原因.我试图通过传递

Ok looks like I was able to figure out why the measurement was inaccurate. I was trying to get a measurement of the listview's height by passing

listItem.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

对于具有可变/动态高度的 ListItem,这是行不通的.测量必须知道至少一个变量,在这种情况下它将是恒定宽度.因此,首先使用以下方法计算您知道将保持不变的列表视图的所需宽度:

For ListItem's with variable/dynamic height, this will not work out. The measurement has to know at least one variable and in this case it will be the constant width. So, first calculate the desired width of the listview which you know is going to be constant, by using:

int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);

然后将其传递给 listitem 度量.完整代码如下:

and then pass it to the listitem measure. Full code is given below:

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

    int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
    int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);

        if(listItem != null){
            // This next line is needed before you call measure or else you won't get measured height at all. The listitem needs to be drawn first to know the height.
            listItem.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
            listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
            totalHeight += listItem.getMeasuredHeight();

        }
    }

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

请注意这是一种骇人听闻的实现,不是推荐的方法.请参阅 如何放置 ListView在不折叠的情况下进入 ScrollView? 并在实施之前准确了解您在做什么.

Please Note This is a hackish implementation and isn't the recommended way. Please see How can I put a ListView into a ScrollView without it collapsing? and understand exactly what you are doing before implementing this.

这篇关于Android Listview 测量高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆