【问题标题】:Android - Get ListView item height?Android - 获取 ListView 项目高度?
【发布时间】:2011-03-22 15:27:45
【问题描述】:

当列表中没有实际项目时,有没有办法在代码中获取 ListViewItem 的高度?

我的 ListViewItem 布局:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight">
...
</LinearLayout>  

我已经尝试使用 Inflater 获得它:

View convertView = LayoutInflater.from( this )
    .inflate( R.layout.mail_list_row, null );
int itemHeight = convertView.getHeight();

但它返回 0;

谢谢!

【问题讨论】:

  • 你的行中有什么东西吗?因为 listPreferredItemHeight 是对 android 资源的引用,我认为它本身不是一个值:developer.android.com/reference/android/…
  • 开头列表为空
  • 在绝大多数情况下,您只需要一个固定的已知高度。只需在单元格布局中的 xml 中设置 minHeight。仅此而已。

标签: android user-interface listview layout listviewitem


【解决方案1】:

在 android 中,只有在渲染完成时,才会为视图分配宽度和高度。因此,除非您的列表至少呈现一次,否则您将不会获得 listItemHeight。您的问题的解决方案可能是您设置列表项的一些最小高度,以便您至少有一些东西可以使用,而不是硬编码高度和宽度。

【讨论】:

  • 另外this SO answer似乎指向android:minHeight的方向。
  • 哟兄弟..尝试设置列表视图高度的小时对我来说是一种很好的方式。但是设置 minHeight 给了我一线希望。
【解决方案2】:

试试这个,它会为你工作。

private static final int UNBOUNDED = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

// To calculate the total height of all items in ListView call with items = adapter.getCount()
public static int getItemHeightofListView(ListView listView, int items) {
    ListAdapter adapter = listView.getAdapter();

    int grossElementHeight = 0;
    for (int i = 0; i < items; i++) {
        View childView = adapter.getView(i, null, listView);
        childView.measure(UNBOUNDED, UNBOUNDED);
        grossElementHeight += childView.getMeasuredHeight();
    }
    return grossElementHeight;
}

【讨论】:

  • 感谢代码,这适用于获取尚未呈现的行的大小,但问题是询问尚未插入 ListView 的行的高度。
  • 行是在列表视图适配器的getView方法中形成的,所以你可以简单地在getView中找到行的高度
  • @AshishDwivedi 我也遇到过类似的问题,您能建议一下吗?
  • 例如,如果您有一个长文本视图,该文本视图在子视图中包含多行,则此方法将不起作用。您需要指定宽度。
  • @Appu,您能否描述一下您的问题。 .
【解决方案3】:

正如上面的 hariseldon78 所指出的,这些解决方案都不能解决真正的问题,即在呈现之前确定列表项行的高度。我遇到了同样的问题,因为我想将一些图像缩放到我的 ListView 项目行的高度,并且不想将它们缩放到固定值。如果主题导致我的行布局的其他部分中的文本高度不同,我想要高度,以便在我的适配器的 getView 例程中我可以相应地调整 bmap 的大小。我一直在努力解决 getHeight 和所有测量高度报告为零的问题,直到该行被渲染。对我来说,后来看到正确的高度为时已晚。

我的解决方案是第一次通过 getView 创建一个 onLayoutChangedListener() 并且仅针对第 0 行。一旦第一个位置 (0) 的 getView 完成执行,侦听器就会触发,此时“底部”参数会告诉你行的高度。我将此记录在自定义适配器类变量中,因此它可以作为高度参数使用,而无需再次获取高度。

侦听器在其执行过程中注销自己。这为第 1-N 行提供了适当的高度,但不为第 0 行提供了适当的高度。对于第零行,我做了一些非常讨厌的事情。在设置另一个自定义适配器类变量来控制递归之后,我让我的侦听器再次为第 0 行调用 getView。第二次 getView(0) 运行它不会设置监听器,并且会找到一个有效的高度参数来操作,一切都很好。

代码在下面 - 无需告诉我这是多么糟糕 - 如果 android 不必让它那么难告诉我正在创建的视图有多大,当我完成基于渲染填充视图时表面的参数我不必做这种丑陋的事情,但它确实有效。对不起,如果代码格式很糟糕......

int mHeight = 0;

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
... usual boiler plate stuff
    // JUST THE FIRST TIME
    if (position == 0 && mHeight == 0) {
        final View ref = convertView;
        convertView.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);
                    mHeight = bottom;
                    firstTime = false;

                    //  NOW LETS REGET THE FIRST VIEW WITH THE HEIGHT CORRECT
                    int visiblePosition = getListView().getFirstVisiblePosition();
                    View view = getListView().getChildAt(0 - visiblePosition);
                    getListAdapter().getView(0, view, getListView());
                    // RECURSION LOL
            }
        });
    }

    // Configure the view for this row
    ....

    // HOW BIG IS THE VIEW?
    // NOW IF NOT FIRSTTIME (MHEIGHT != 0)
    if (mHeight != 0) {
        // DO OUR IMAGE SETUP HERE CAUSE mHeight is RIGHT!
        Log.d(TAG, "mHeight=" + mHeight);
    }

        return convertView;
}

【讨论】:

  • 您可以使用以下布局在pseudo-android-xml 的第一段中为您提供您想要的内容:&lt;LinearLayout orientation="horizontal" width="fill" height="wrap"&gt;&lt;ImageView width="wrap" height="fill" scaleType="fitCenter" adjustViewBounds /&gt;&lt;TextView width="0dp" weight="1.0" height="wrap" /&gt;
  • @MikeKogan 谢谢,这对我也有用。我在相同大小的存储桶中遇到了屏幕问题,但分辨率不同。直到有更好的方法来解决这个问题,这似乎是要走的路。
【解决方案4】:

Dwivedi Ji 的代码的优化版本,带有分隔线高度且没有不必要的参数:

private int calculateHeight(ListView list) {

    int height = 0;

    for (int i = 0; i < list.getCount(); i++) {
        View childView = list.getAdapter().getView(i, null, list);
        childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        height+= childView.getMeasuredHeight();
    }

    //dividers height
    height += list.getDividerHeight() * list.getCount();

    return height;
}

【讨论】:

  • 我认为分频器计数应该是list.getCount() - 1
  • 这给出了所有项目的高度。所以items参数是必要的,因为它告诉你要添加多少项目到总高度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多