I inflate this view, and add it to my ListView as a header. I am trying to make it 500dp high (hard coded, for the sake of this example)
<?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>
The ListView does not respect the authoritah of its header and wraps it on its content. Can anyone please explain what happens?
The key to understand what's going on is figuring out how ListView headers and footers are implemented. They're a trick: the moment you add the first header or footer to your ListView, your ListAdapter is wrapped in a HeaderViewListAdapter
(happens on line 270 of ListView.java). The HeaderListViewAdapter is a list adapter that tweaks count
and position
values to include the headers and footers; headers and footers become normal list items that the system manages for you.
If you look at line 207 of HeaderListViewAdapter.java, you'll see that the getView
implementation ignores the parent
view when adding a header or footer. This has the effect that its mLayoutParams
doesn't get initialized from XML (can't really point you to the source code, just something I've found out over time).
If you then follow the calls to getView
for a bit, past line 2237 of AbsListView.java, and follow the calls for obtainView
for a bit and search for LayoutParams
(which is what I just did) you end up at line 1182 of ListView.java. Here you see that, if the layout params are null
when the child view is measured, it calls out to generateDefaultLayoutParams()
, which is implemented on line 6065 of AbsListView.java:
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
...and that's where your WRAP_CONTENT
is coming from.
As an easy work-around, just wrap the <LinearLayout/>
of your XML inside a <FrameLayout/>
. Keep the 500dp on the LinearLayout and make the FrameLayout have a layout height of WRAP_CONTENT (which will get ignored anyway).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With