2014-09-12 11 views
7

Gonfio questa vista e la aggiungo al mio ListView come intestazione. Sto cercando di renderlo 500dp alta (hard coded, per il bene di questo esempio)L'intestazione di ListView ignora layout_height

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

Il ListView non rispetta l'authoritah della sua intestazione e avvolge sul suo contenuto. Qualcuno può spiegare cosa succede?

risposta

12

La chiave per capire cosa sta succedendo è capire come vengono implementate le intestazioni ei piè di pagina di ListView. Sono un trucco: nel momento in cui aggiungi la prima intestazione o il piè di pagina al tuo ListView, il tuo ListAdapter è incapsulato in un HeaderViewListAdapter (succede su line 270 of ListView.java). HeaderListViewAdapter è un adattatore di lista che modifica i valori count e position per includere intestazioni e piè di pagina; intestazioni e piè di pagina diventano normali voci di elenco che il sistema gestisce per te.

Se si guarda line 207 of HeaderListViewAdapter.java, si noterà che l'implementazione getView ignora la vista parent quando si aggiunge un'intestazione o un piè di pagina. Questo ha l'effetto che il suo mLayoutParams non viene inizializzato da XML (non può davvero indirizzarti al codice sorgente, solo qualcosa che ho scoperto nel tempo).

Se poi si seguono le chiamate a getView per un po ', passato line 2237 of AbsListView.java, e seguire le richieste di obtainView per un po' e la ricerca di LayoutParams (che è quello che ho appena fatto) si finisce a line 1182 of ListView.java. Qui si vede che, se i params layout sono null quando la vista del bambino si misura, si chiama a generateDefaultLayoutParams(), che viene implementato su line 6065 of AbsListView.java:

@Override 
protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 
    return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 
     ViewGroup.LayoutParams.WRAP_CONTENT, 0); 
} 

... e questo è dove il vostro WRAP_CONTENT proviene da .

Come semplice soluzione, è sufficiente avvolgere lo del codice XML all'interno di <FrameLayout/>. Mantieni il 500dp sul LinearLayout e fai in modo che FrameLayout abbia un'altezza di layout di WRAP_CONTENT (che verrà comunque ignorata).

+1

+1 per una risposta elaborata. Non sono sicuro di cosa pensare di questo; bug - o funzionalità? L'astrazione, o il modello mentale si rompe quando le cose non funzionano come previsto. –

+0

fantastico, grazie! – kiruwka

Problemi correlati