【问题标题】:Why do ListView items not grow to wrap their content?为什么 ListView 项目不会增长来包装它们的内容?
【发布时间】:2009-11-02 13:20:10
【问题描述】:

我有一个相当复杂的 ListView,具有可变的列表项高度。在某些情况下,我需要在列表项中显示一个额外的视图,默认情况下它是隐藏的(View.GONE)。通过启用它 (View.VISIBLE),列表项的高度会增加(或者至少应该如此)。

问题: 即使我将项目的根布局声明为wrap_content,并将项目中的每个组件声明为fill_parent,我隐藏/显示的应该更改项目高度的视图在底部而不是其父级(项目布局)高度增长以完全显示它。

是否有任何我可能遗漏的与 ListView 和项目布局和项目高度相关的问题?

更多观察:

出于测试目的,我现在将列表项布局缩减为仅包含根 LinearLayout 和 ImageView。当我将 LinearLayout 高度设置为例如200dip 和 ImageView 到 fill_parent,我预计 ImageView 会增长,直到达到其父级设置的 200dip 限制。

但是,图像只会与其位图资源一样高(就像我将其设置为 wrap_content)并且整个列表项将具有相同的高度(即就像我将其设置为wrap_content)。

但是,如果我将图像高度设置为例如200dip,那么列表项的高度会增加,项的布局也会增加。

换句话说,列表项布局的layout_height 被完全忽略,ImageView 上除硬编码像素值之外的任何高度值也是如此。

【问题讨论】:

  • 嗨.. Matthias 请给我一个工作示例。我也面临同样的问题,但不清楚你是如何解决的。问题。

标签: android listview


【解决方案1】:

我设法解决了这个问题,但我不明白为什么

正如我所提到的,我已将列表项布局的 layout_height 设置为 wrap_content(因为 fill_parent 在这里毫无意义,考虑到 ListView 无限高)。

但是,我已将该布局inside 的所有视图的layout_height 设置为fill_parent。将它们设置为 wrap_content 时问题消失了。

这引发了另外两个问题:

1) 当父wraps_content 时,向fill_parent 询问的视图的语义是什么?哪个尺寸请求优先?

2) 如果fill_parent 显然不起作用,我将如何让视图填充列表项?

感谢您的意见。

【讨论】:

  • 感谢那个 Matthias =) 我遇到了同样的问题。我还将 layout_height 设置为“fill_parent”。我认为这很明显。但是你是对的,当设置为“wrap_content”时,它解决了这个问题。奇怪...
  • 谢谢!这让我很生气。
  • 好的,由于某种原因,我遇到了类似的问题,但是当列表中只有一个项目时,整个列表视图与第一次显示相比会太小。所以当我增加项目大小时,视图不会增长。我必须将视图设置为“fill_parent”才能工作。现在,我需要看看里面有很多物品会发生什么。
  • 第一个问题:父母wraps_content 和孩子fill_parent 没有意义。当 android 计算布局所需的空间时,它会移动到父节点。父母说它需要足够的空间来包裹它的孩子,所以 android 询问它的孩子需要多少空间。但是它的孩子不知道,因为他们想要父母占用多少。简而言之:父wraps_content与子fill_parent冲突。
  • 第二个问题:ListView 用于显示未指定数量的项目,这就是它可以滚动的原因。如果您想填充屏幕而不是让额外的项目可滚动,我建议使用 LinearLayout 与权重,例如addView(item, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 0, 1));。这些项目现在将占据与您分配的权重成正比的高度,同时填充父项(前提是指定了父项的高度)。
【解决方案2】:

试试这个: http://www.java2s.com/Code/Android/UI/setListViewHeightBasedOnChildren.htm

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

【讨论】:

  • 欢迎来到 Stack Overflow!虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供参考链接。
  • 你在哪里运行这个方法,以便在孩子重新测量之后?
  • 很好.. 但是你需要这个来使params.height 标记为px 值而不是dp 值.. int dpValue = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); //dp value float density = context.getResources().getDisplayMetrics().density; params.height = (int) Math.ceil(dpValue * density);//pixels value
  • 你在哪里运行这个方法,以便在孩子重新测量之后?
  • 我认为不需要调用listView.requestLayout();,因为方法setLayoutParams 已经有相同的调用。
【解决方案3】:

你是如何膨胀你的行的?

如果您现在不使用它,请尝试使用LayoutInflater#inflate(layoutId, parent, false)(其中parent 是提供给getView()newView()AdapterView):

v = getLayoutInflater().inflate(R.layout.list_item, parent, false);

【讨论】:

  • 嗨,马克,向 inflate() 提供根视图的语义是什么,但将 attachToRoot 设置为 false?如果 inlated 视图没有附加到 rootView,那么该视图还做了什么?
  • 对不起,我忘了说:我为 rootView 传递了 null,为 attachToRoot 传递了 false。毕竟,视图是由 adapter.getView() 返回的,我希望它负责将其添加到视图树中。
  • 引用文档,“如果为 false,则 root 仅用于为 XML 中的根视图创建正确的 LayoutParams 子类。”否则,Android 不知道如何将 child 附加到 parent,因此我认为它使用了一个非常通用的 LayoutParams。
  • 让父母为我工作并解决了我的行高问题
  • 这成功了! v = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false); (而不是我之前的 v = View.inflate(getContext(), R.layout.dashboard_card_item, null);
【解决方案4】:

布局的问题可能是因为 ScrollView 是包装器

我偶然发现了一些笔记 http://developer.android.com/reference/android/widget/ExpandableListView.html

"...注意:如果父级的大小也没有严格指定(例如,如果父级是 ScrollView,则不能指定 wrap_content,因为 XML 中 ExpandableListView 的 android:layout_height 属性它也可以是任意长度。但是,如果 ExpandableListView 父级具有特定大小,例如 100 像素,则可以使用 wrap_content。"

我删除了包装 ScrollView 并且线性布局开始正常工作。现在它只是了解如何将这些东西包装到 ScrollView。上帝帮助我

但无论如何,这确实是一种奇怪的行为。我认为 fill_parent 的措辞并不正确。使用 heirarchyviewer 工具时,我总是看到 layout_width 和 leayout_height 的 WRAP_CONTENT 和 MATCH_PARENT 值。所以可能 fill_parent 实际上意味着 match_parent 这让我陷入认知失调。

【讨论】:

    【解决方案5】:

    我使用“AbsListView.LayoutParams”在“Adapter.getView()”中手动配置宽度和高度。

    【讨论】:

      【解决方案6】:

      如果您使用自定义 View in 作为正在调整大小的列表项,那么您可以从 PeBek 的答案中获取并在构造 View 时执行此操作

      addOnLayoutChangeListener(
                  new OnLayoutChangeListener() {
                      @Override
                      public void onLayoutChange(View _, int __, int ___, int ____, int bottom, int _____, int ______,
                                                 int _______, int old_bottom) {
                          final ListView list_view = (ListView) getParent();
                          final ViewGroup.LayoutParams params = list_view.getLayoutParams();
                          params.height += bottom - old_bottom;
                          list_view.setLayoutParams(params);
                          list_view.requestLayout();
                      }
                  });
      

      View 调整大小时,我将运行此回调方法,它会更新ListView 高度以包含高度变化(底部增量)。其他值,如果它们证明对您有用,则为 view(参考视图)、lefttoprightbottomold_leftold_topold_right、@ 987654334@。它适用于展开和折叠视图。

      OnLayoutChangeListener 需要

      API 11,不知道是否有向后兼容的方式。

      【讨论】:

      • 注意:addOnLayoutChangeListener() 需要 api 级别 11
      • @larham1 指出,我写这篇文章时一定忽略了这一点。
      【解决方案7】:

      我遇到了同样的问题:我想在我的 Activity 中有一个列表,当设备处于垂直方向而不是水平方向时,它会填满整个屏幕。 我使用高度必须为 fill_parent 的线性布局解决问题,并将列表中项目的高度设置为 0dp,而 layout_weight 设置为 1。

      android:layout_weight="1"
      android:layout_height="0dp"
      

      【讨论】:

        【解决方案8】:

        这对我有用

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        
            android:padding="@dimen/activity_vertical_margin">
        
            <TextView
                android:id="@+id/tv_status"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="17sp"
                android:text="@string/text_list_devices" />
        
            <ListView
                android:id="@+id/lv_paired"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/activity_vertical_margin"
                android:cacheColorHint="#00000000"
                android:layout_above="@+id/signup_t"
                android:layout_below="@id/tv_status"
                />
        
            <Button
        
                android:id="@+id/signup_t"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:textColor="@android:color/white"
                android:layout_alignParentBottom="true"
                android:text="Print All Records"
                android:typeface="sans"
                android:layout_marginLeft="45dp"
                android:layout_marginRight="45dp"
                android:textSize="24sp"
                android:background="@drawable/selector_for_button"
                android:textStyle="bold" />
        </RelativeLayout>
        

        【讨论】:

          【解决方案9】:

          列对齐注意事项:

          • 容器 LinearLayout 元素使用水平方向和 android:layout_width 作为 match_parent。
          • TextView 元素使用 android:layout_width="0dp"
          • 两个 TextView 元素中的每一个都使用 android:layout_weight="1" 所以 他们使用等量的可用宽度。
          • 每个 TextView 元素的 android:layout_width 属性设置为 “0dp”。

          【讨论】:

            猜你喜欢
            • 2013-11-07
            • 2021-06-26
            • 2015-12-06
            • 1970-01-01
            • 1970-01-01
            • 2018-12-12
            • 1970-01-01
            • 2016-01-13
            • 1970-01-01
            相关资源
            最近更新 更多