ListView头部忽略layout_height属性

7

我将此视图扩展并将其作为标题添加到我的ListView中。我试图使它的高度为500dp(硬编码,仅为此示例而设)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"
              android:layout_width="match_parent" android:background="@drawable/repeat_background"
              android:layout_height="500dp">

    <ImageView android:id="@+id/filter_menu" android:src="@drawable/ic_sort"
               android:layout_gravity="center_vertical" android:padding="8dp"
               android:layout_weight="0"
               android:layout_width="wrap_content" android:layout_height="wrap_content"
               android:onClick="showPopup"/>

</LinearLayout>

ListView不尊重其标题的权威性,并在其内容上进行换行。请问有人能解释一下发生了什么吗?

1个回答

14

理解ListView头部和尾部是如何实现的,是理解这个问题的关键。它们是一个技巧:当你向ListView添加第一个头部或尾部时,你的ListAdapter就会被包装在一个HeaderViewListAdapter中(发生在ListView.java的第270行)。HeaderViewListAdapter是一个列表适配器,它调整countposition值以包括头部和尾部;头部和尾部成为系统为你管理的普通列表项。

如果您查看HeaderListViewAdapter.java的第207行, 您会发现getView实现在添加页眉或页脚时忽略了parent视图。这样做的效果是,它的mLayoutParams没有从XML中初始化(我无法真正为您指出源代码,只是我随着时间的推移发现的一些事情)。
如果您跟随一段时间的对getView的调用,经过AbsListView.java的2237行,并且继续跟随一段时间的对obtainView的调用,并搜索LayoutParams(这正是我刚才所做的),那么您最终会到达ListView.java的1182行。在这里,您可以看到,如果当子视图被测量时布局参数为null,它会调用generateDefaultLayoutParams(),该方法实现在AbsListView.java的6065行
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
    return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}

......这就是你的WRAP_CONTENT来自的地方。

作为一个简单的解决方法,只需将XML中的<LinearLayout/>包装在<FrameLayout/>中。保持LinearLayout上的500dp,并使FrameLayout具有WRAP_CONTENT的布局高度(无论如何都会被忽略)。


1
对于这个问题,我不确定该怎么看待:是个bug还是特性?当事情未能按照预期工作时,抽象或者心理模型就会崩溃。 - Glenn Bech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接