web-dev-qa-db-fra.com

Supprimer l'en-tête de listView

J'ai quelques problèmes lorsque j'essaie de supprimer l'en-tête d'une listView. Au début, j'utilise addHeaderView() pour l'ajouter, mais lorsque je change de présentation, je veux qu'il disparaisse, mais removeHeaderView() ne fonctionne pas ...

J'ai aussi essayé de régler la visibilité sur GONE et cela ne disparaît pas ...

Que puis-je faire?

Merci d'avance

22
hasiertxo

Essayez l'approche mentionnée ci-dessous.

Les méthodes Android ListView#addHeaderView et ListView#addFooterView sont étranges: vous devez ajouter les vues d'en-tête et de pied de page avant de configurer l'adaptateur de ListView afin que ListView puisse prendre en compte les en-têtes et les pieds de page. Sinon, vous obtenez une exception. Ici, nous ajoutons un ProgressBar (spinner) comme headerView:

// spinner est une barre de progression

listView.addHeaderView(spinner);

Nous aimerions être en mesure de montrer et de cacher ce spinner à volonté, mais le supprimer de façon pure et simple est dangereux car nous ne pourrions plus jamais l'ajouter sans détruire ListView - souvenez-vous, nous ne pouvons pas ajouter HeaderView après avoir c'est adaptateur:

listView.removeHeaderView(spinner); //dangerous!

Alors cachons-le! Il s'avère que c'est difficile, aussi. Si vous masquez simplement la vue en rotation, vous obtenez une zone d’en-tête vide, mais toujours visible.

Maintenant, essayez de cacher le spinner:

spinner.setVisibility(View.GONE);

Résultat: zone d'en-tête toujours visible avec un espace moche:

La solution consiste à placer la barre de progression dans un LinearLayout qui englobe son contenu et masque le contenu. De cette façon, LinearLayout encapsulant se réduira lorsque son contenu sera masqué, ce qui produira un headerView techniquement toujours présent, mais ayant une valeur 0dip élevée:

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

Ensuite, définissez la mise en page comme en-tête:

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

Et quand nous devons le cacher, cachez le contenu de la mise en page, pas la mise en page:

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

L'en-tête disparaît de la vue. Pas plus d'espace laide au sommet!

52
Praful Bhatnagar

La plupart des gens n'aiment pas utiliser AddHeaderView. Cependant, j'ai parfois trouvé cela très pratique d'éviter de modifier des adaptateurs complexes ou si les en-têtes ne leur sont pas très proches. 

Avec cette astuce simple, vous pourrez supprimer/ajouter des en-têtes de manière transparente :

J'ajoute une LinearLayout vide avec orientation vertical et une hauteur wrap_content, en tant que vue d'en-tête unique (laissez mListView la cible listView):

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

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

Ensuite, je peux ajouter des éléments aléatoires, n'importe où, à la liste en tant qu'en-tête, même lorsque la liste est pleine:

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

Vous pouvez également supprimer tous les en-têtes, à tout moment:

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

Vous avez l'idée ... J'espère que ça aide!

17
rupps

Le problème est que vous créez toujours un nouvel objet quand vous faites:

 View headerView = someView

Donc, la nouvelle vue n'est pas la même que la vue déjà ajoutée en tant qu'en-tête de listView, essayez ceci:

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);
            }
        }
3
sagits

drawerLogoView est mon aperçu, voici ce que je fais:

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

Ainsi, il devient invisible: D Pour le montrer, vous pouvez utiliser ceci:

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

Vous pouvez vérifier si le nombre d'en-têtes> 0 puis supprimer l'en-tête et l'ajouter à nouveau.
Cela fonctionne très bien pour moi.

 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
 }
1
Hamid

J'ai rencontré ce problème dans un scénario légèrement déguisé: le ListView que je traitais provenait de PreferenceFragment et l'en-tête représente une PreferenceCategory. Ainsi, ma liberté d'installation du ListView était sévèrement limitée. Mais il y avait deux approches (inspirées en partie par d’autres réponses sur cette page). L'une consistait à ajouter une mise en page personnalisée à ma PreferenceCategory (à l'aide d'une classe qui extends Android.preference.PreferenceCategory, voir Rubriques personnalisées PreferenceCategory). Mais j’ai trouvé une solution de contournement plus simple: pour la première préférence de cette PreferenceCategory, je remplace onCreateView():

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

Si vous utilisez addHeaderView (), vous ne pouvez pas supprimer votre en-tête après cela.

Donc, n'utilisez pas addHeaderView (). Créez plutôt votre propre adaptateur qui Fusionne votre liste principale de vues avec votre en-tête. Bien que mon MergeAdapter ne traite pas votre cas spécifique, vous pouvez l'utiliser pour voir Le concept de fusion de plusieurs sources de lignes:

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

0
Miloš