为什么ListView项目不会增长以包装其内容?

时间:2009-11-02 13:20:11

标签: android listview

我有一个相当复杂的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上的任何高度值都是硬编码像素值。

9 个答案:

答案 0 :(得分:55)

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

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

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

这提出了另外两个问题:

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

2)如果fill_parent显然不起作用,我如何填写列表项?

感谢您的投入。

答案 1 :(得分:28)

试试这个: 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();
    }     
}

答案 2 :(得分:21)

你是如何给你的行充气?

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

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

答案 3 :(得分:14)

布局问题可能是由ScrollView作为包装器引起的

我偶然发现了一些注意事项 http://developer.android.com/reference/android/widget/ExpandableListView.html

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

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

如果您正在使用自定义View作为要调整大小的列表项,那么您可以从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高度以包含高度变化(delta底部)。如果其他值对您有用,则view(对视图的引用),lefttoprightbottom,{{1 },old_leftold_topold_right。它适用于展开和折叠视图。

old_bottom需要

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

答案 6 :(得分:0)

我遇到了同样的问题:我希望在我的活动中有一个列表,当设备处于垂直方向而不是水平方向时,该列表会填满所有屏幕。 我使用高度必须为fill_parent的al Linear Layout解决问题,并将layout_weight设置为1时将列表中项目的高度设置为0dp。

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

答案 7 :(得分:0)

这对我有用

<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>

答案 8 :(得分:0)

关于列对齐的注意事项:

  • 容器LinearLayout元素使用水平方向,并且 android:layout_width作为match_parent。
  • TextView元素使用android:layout_width =“ 0dp”
  • 两个TextView元素均使用android:layout_weight =“ 1”,因此 他们使用相等数量的可用宽度。
  • 每个TextView元素的android:layout_width属性设置为 “ 0dp”。