2012-11-28 19 views
20

Sto riscontrando alcuni problemi durante il tentativo di rimuovere l'intestazione da un listView. Inizialmente utilizzo addHeaderView() per aggiungerlo, ma quando passo a un altro layout voglio che scompaia ma removeHeaderView() non funziona ...Rimuovi intestazione da listView

Ho anche provato a impostare la visibilità su GONE e non scompare ...

Cosa posso fare?

Grazie in anticipo

risposta

0

Se si utilizza addHeaderView(), non è possibile eliminare l'intestazione dopo.

Quindi, non utilizzare addHeaderView(). Piuttosto, crea il tuo adattatore che miscela la tua lista principale di Views con la tua intestazione. Mentre la mia MergeAdapter non gestire il vostro caso specifico, è possibile utilizzarlo per vedere il concetto di fusione più fonti di fila:

https://github.com/commonsguy/cwac-merge

+0

è possibile eliminare vista intestazione se si dispone di una variabile per puntare a intestazione, si veda questo link: http://stackoverflow.com/a/39286390/1817569 – Hamid

48

Provare l'approccio menzionato seguente ..

Android ListView#addHeaderView e ListView#addFooterView i metodi sono strani: devi aggiungere le viste dell'intestazione e del piè di pagina prima di impostare l'adattatore di ListView in modo che ListView possa prendere in considerazione intestazioni e piè di pagina - altrimenti otterrai un'eccezione. Qui aggiungiamo una ProgressBar (filatore) come headerView:

// filatore è un ProgressBar

listView.addHeaderView(spinner); 

Vorremmo essere in grado di mostrare e nascondere quel filatore a volontà, ma la rimozione a titolo definitivo è pericoloso, perché non saremmo mai in grado di aggiungere di nuovo senza distruggere il ListView - ricordate, non possiamo addHeaderView dopo che abbiamo è l'adattatore:

listView.removeHeaderView(spinner); //dangerous! 

Quindi cerchiamo di nasconderlo! Risulta anche difficile. Solo nascondendo la vista dello spinner si ottiene un'area dell'intestazione vuota, ma ancora visibile.

Ora provate a nascondere il filatore:

spinner.setVisibility(View.GONE); 

Risultato: area di intestazione ancora visibile con uno spazio brutta:

La soluzione è quello di mettere il progresso barra in un LinearLayout che avvolge il suo contenuto e nasconde il contenuto.In questo modo il LinearLayout incarto collasserà quando il suo contenuto è nascosto, risultando in un headerView tecnicamente ancora presente, ma 0dip alta:

<LinearLayout 
     xmlns:a="http://schemas.android.com/apk/res/android" 
     android:orientation="vertical" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
    <!-- simplified --> 
     <ProgressBar 
     android:id="@+id/spinner" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
    </LinearLayout> 

Quindi impostare il layout come intestazione:

spinnerLayout = getLayoutInflater().inflate(R.layout.header_view_spinner, null); 
listView.addHeaderView(spinnerLayout); 

e quando abbiamo bisogno di nasconderlo, nascondere il contenuto del layout di, non il layout:

spinnerLayout.findViewById(R.id.spinner).setVisibility(View.GONE); 

Ora il colpo di testa scompare dalla vista. Niente più brutti spazi in alto!

+2

+1 fantastico - grandi opere per me – Dori

+0

Grande Lavoro, ottimo modo per spiegare l'intero processo. –

+0

Uomo con kg di cervello in più – Sayka

14

La maggior parte delle persone non ama utilizzare AddHeaderView, tuttavia a volte ho trovato molto conveniente, per evitare di modificare gli adattatori complessi o se le intestazioni non sono molto correlate a loro.

Con questo facile trucco si sarà in grado di senza rimuovere/aggiungere intestazioni:

aggiungo un vuoto LinearLayout con orientation vertical, e l'altezza wrap_content, come unica intestazione View (lasciare mListView essere il bersaglio listView) :

LinearLayout mCustomHeaders=new LinearLayout(context); 
mCustomHeaders.setOrientation(LinearLayout.VERTICAL); 

mListView.addHeaderView(mCustomHeaders); 
mListView.setAdapter (.......) 

Thenafter, posso aggiungere cose a caso, ovunque, per la lista come intestazione, anche se la lista è piena:

mCustomHeaders.add(myHeaderView1); 
mCustomHeaders.add(myHeaderView2); 
mCustomHeaders.add(myHeaderView3); 

È possibile anche eliminare tutte le intestazioni, in qualsiasi momento:

mCustomHeaders.removeAllViews(); // will erase all headers 

Si ottiene l'idea .... Speranza che aiuta!

+0

Questo ha funzionato molto bene. –

1

Dove drawerLogoView è la mia headerview, ecco quello che faccio:

drawerLogoView = mInflater.inflate(R.layout.navigation_drawer_custom_layout, null); 
    mDrawerList.addHeaderView(drawerLogoView,null,false);     
    LinearLayout layOut = ((LinearLayout)drawerLogoView.findViewById(R.id.NavProfilePreviewLayout)); 
    layOut.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 0)); 

In questo modo, diventa invisibile: D Per vederlo di nuovo, è possibile utilizzare questo:

LinearLayout layOut = ((LinearLayout)drawerLogoView.findViewById(R.id.NavProfilePreviewLayout)); 
    layOut.setLayoutParams(newRelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); 
0

ho incontrato questo problema in uno scenario leggermente camuffato: il ListView di cui mi occupavo proveniva da PreferenceFragment e l'intestazione rappresenta un PreferenceCategory. Quindi, la mia libertà di configurazione di ListView era severamente limitata. Ma c'erano due approcci (in parte ispirati ad altre risposte in questa pagina). Uno era di aggiungere un layout personalizzato al mio PreferenceCategory (utilizzando una classe che extends android.preference.PreferenceCategory, vedere Custom PreferenceCategory Headings). Ma ho trovato una soluzione più semplice: per la prima preferenza in questo PreferenceCategory, mi ignorare onCreateView():

@Override public View onCreateView(ViewGroup parent) { 
    parent.setTop(-parent.getChildAt(0).getTop()); 
    return super.onCreateView(parent); 
} 
3

Il problema è che si sta sempre creando un nuovo oggetto quando si esegue:

View headerView = someView 

Così il nuova visione non è la stessa come la vista già aggiunto come intestazione listView, provate questo:

View headerView = inflater.inflate(R.layout.adapter_datatable_saleitem_header, null, false); 
     headerView.setTag(this.getClass().getSimpleName() + "header"); 
     if (listView.getHeaderViewsCount() > 0) { 
      View oldView = listView.findViewWithTag(this.getClass().getSimpleName() + "header"); 
      if (oldView != null) { 
       listView.removeHeaderView(oldView); 
      } 
     } 
1

è possibile controllare se il colpo di testa di conteggio> 0 quindi rimuovere l'intestazione e aggiungerlo di nuovo.
funziona bene per me.

View _headerView; 
private void function HandleHeaderView(){ 
     if(listView.getHeaderViewsCount() > 0) 
     { 
      listView.removeHeaderView(_headerView); 
     } 

     /* Add list view header */ 
     _headerView = GetHeaderView(); 
     listView.addHeaderView(_headerView); 
} 


private View GetHeaderView() 
{ 
     View header = getLayoutInflater().inflate(R.layout.header_layout, null); 
     // TODO: ... 

     return header 
}