计算ListView每一行的高度 [英] Calculating the height of each row of a ListView

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

问题描述

我正在尝试使用 ListView 滚动 ListView 的背景.我的方法基于 货架,但货架上的所有东西都具有相同的高度,我不能做出同样的保证.

I am trying to make the background of a ListView scroll with the ListView. I am basing my approach on this class in Shelves, but while in Shelves everything has the same height, I can't make the same guarantee.

我有一个这样的活动:

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = (ListView) findViewById(R.id.listView);

        List<String> items = new ArrayList<String>();
        for(int i=0; i < 100; ++i) {
            items.add("Hello " + i);
        }
        CustomArrayAdapter adapter = new CustomArrayAdapter(this, items);

        listView.setAdapter(adapter);
    }
}

CustomArrayAdapter 在哪里:

Where CustomArrayAdapter is:

public class CustomArrayAdapter extends ArrayAdapter<String> {
    private List<Integer> mHeights;

    public View getView(int position, View convertView, ViewGroup parent) {
        //snip
    }
}

我想要做的是用视图行的高度填充适配器中的 mHeights.

What I want to do is populate mHeights in the adapter with heights of the rows of the view.

我的主要尝试是在 getView() 中执行此操作:

My main attempt was to do this, in getView():

if(row.getMeasuredHeight() == 0) {
    row.measure(
        MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY));
}
mHeights.set(position, row.getMeasuredHeight());

我已经尝试了几种方法来做到这一点,但我什么都做不了.

I've tried several ways to do this, but I can't get anything to work.

getView中,如果我调用getHeight(),我得到的返回值为0,而如果我调用getMeasuredHeight(),我得到一些非零但不是真正的高度.如果我向下滚动然后再次向上滚动(将其中一行移出视图)getHeight() == getMeasuredHeight() 并且两者都具有正确的值.如果我只是在运行时更新 getView 中的 mHeights(通过说 mHeights.set(position, row.getHeight()); 它可以工作 - 但只有在我滚动到 ListView 的底部之后.我试过在 getView 方法中调用 row.measure() ,但这仍然导致 getHeight() 在第一次运行时为 0.

In getView, if I call getHeight() I get a return value of 0, while if I call getMeasuredHeight(), I get something non-zero but not the real height. If I scroll down and then up again (taking one of the rows out of view) getHeight() == getMeasuredHeight() and both have the correct value. If I just update mHeights in getView as I go (by saying mHeights.set(position, row.getHeight()); it works - but only after I've scrolled to the bottom of the ListView. I've tried calling row.measure() within the getView method, but this still causes getHeight() to be 0 the first time it is run.

我的问题是:如何使用 ListView 行的正确高度计算和填充 mHeights?我看过一些类似的问题,但它们似乎不是我要找的.ViewTreeObserver 方法看起来很有前景,但我不知道如何强制调用 getView()(或者,迭代 ListView 的行).调用 adapter.notifyDataSetChanged() 会导致无限(尽管非阻塞)循环.

My question is this: how do I calculate and populate mHeights with the correct heights of the rows of the ListView? I've seen some similar questions, but they don't appear to be what I'm looking for. The ViewTreeObserver method seems promising, but I can't figure out how to force calls to getView() from it (alternately, to iterate the rows of the ListView). Calling adapter.notifyDataSetChanged() causes an infinite (although non-blocking) loop.

  1. 获取视图的实际高度
  2. 如何获取项目的高度列表视图?

这与我之前关于该主题的问题有关,该问题似乎没有抓住要点:ListView 距离列表顶部的距离

This is related to my previous question on the subject, which seems to have missed the point: ListView distance from top of the list

推荐答案

我想出了如何做到这一点.这有点棘手,但确实有效.

I figured out how to do this. It's was a bit tricky, but it works.

微妙之处在于获取已知的布局参数.据我所知, getView() 正在返回初始时间的视图,所以当然它不能有一个高度 - 父级还不知道该行(因为 getView() 的工作是对其进行膨胀),所以我们需要一个回调.

The subtlety was getting layout parameters when they are known. As I learned, getView() is returning the view for the initial time, so of course it can't have a height yet - the parent doesn't know about the row yet (since getView()'s job is to inflate it), so we need a callback.

那个回调可能是什么?事实证明,我只能说它是行视图的 OnLayoutChangeListener().因此,在我的自定义 ArrayAdapter 中的 getView() 中,我为 onLayoutChanged 添加了一个回调,如下所示:

What might that callback be? It turns out, as best I can tell it's the OnLayoutChangeListener() for the row's view. So in getView() in my custom ArrayAdapter, I added a callback for onLayoutChanged like so:

row.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    public void onLayoutChange(View v, int left, int top, int right,
            int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        ref.removeOnLayoutChangeListener(this);
        Log.d("CustomArrayAdapter", "onLayoutChange(" + position + "): height " + (bottom - top));
        mHeights.set(position, (bottom - top));
        if(position > 0) {
            mDistances.set(position, bottom - top + mDistances.get(position-1) + ((ListView)parent).getDividerHeight());
        }
        holderRef.distanceFromTop = mDistances.get(position);
        Log.d("CustomArrayAdapter", "New height for " + position + " is " + mHeights.get(position) + " Distance: " + mDistances.get(position));
    }
});

这里,row是adapter中getView()要返回的view,mHeights是每个高度的列表ListView 的元素,而 mDistances 是以像素为单位的列表视图顶部距离的列表 - 我想要计算的真实事物(即,如果您将整个列表视图首尾相连,我离顶部元素有多远).所有这些都存储在自定义 ArrayAdapter 中.这些列表被初始化为零.

Here, row is the view to be returned by getView() in the adapter, mHeights is a list of the height of each element of the ListView, and mDistances is a list of the distance from the top of the list view in pixels - the real thing that I wanted to calculate (that is, if you laid out the entire list view end to end, how far from the top element i would be from the top). All of these are stored within the custom ArrayAdapter. These lists are initialized to zeroes.

添加这个回调让我可以计算视图的高度.

Adding this callback allowed me to calculate the height of the view.

我的目标是让 ListView 具有随列表滚动的背景.如果有人感兴趣,我把代码放在 GitHub 上,如果有人想查看它:https://github.com/mdkess/TexturedListView

My goal was to have a ListView that has a background that scrolls with the list. If anyone is interested, I put the code up on GitHub if anyone would like to review it: https://github.com/mdkess/TexturedListView

这篇关于计算ListView每一行的高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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