web-dev-qa-db-fra.com

NavigationView get / find disposition d'en-tête

Dans mon NavigationView, j'ai une disposition d'en-tête avec l'id 'viewId' avec des boutons actifs. Pour configurer ces boutons, procédez comme suit dans l'activité onPostCreate:

final View panel = findViewById(R.id.viewId);
panel.setOnClickListener(new View.OnClickListener() {
... setup goes here ...
});

Avec la nouvelle version Android bibliothèque de support, (23.1.), la vue est introuvable, elle renvoie la valeur null. Avec les versions précédentes, cela a bien fonctionné. Est-ce un bug ou est-ce que j'utilise mal cette fonctionnalité? Si oui, comment accéder à la disposition des en-têtes et y ajouter un comportement?

160
khusrav

La version 23.1.0 bascule NavigationView sur l’utilisation de RecyclerView (plutôt que le précédent ListView) et l’en-tête est ajouté en tant qu’un de ces éléments. Cela signifie qu’il n’est pas disponible instantanément d’appeler findViewById() - une passe de mise en page est nécessaire avant de l’attacher au NavigationView.

Pour version 23.1.1 de la bibliothèque de support, vous pouvez maintenant obtenir une référence à la vue d'en-tête à l'aide de getHeaderView():

View headerLayout = navigationView.getHeaderView(0); // 0-index header

Cela présente l’avantage de travailler sur des en-têtes ajoutés via XML et via du code.

Si vous utilisez toujours 23.1.0, comme indiqué dans le bogue associé , vous pouvez gonfler l'en-tête dans le code et utiliser findViewById() pour cela:

View headerLayout = 
    navigationView.inflateHeaderView(R.layout.navigation_header);
panel = headerLayout.findViewById(R.id.viewId);
// panel won't be null

Jusqu'à ce que vous passiez à 23.1.1.

408
ianhanniballake

Maintenant, avec la version 23.1.1 de la bibliothèque de support de conception, vous pouvez utiliser

NavigationView navigationView = (NavigationView) findViewById(R.id.your_nav_view_id);
View header = navigationView.getHeaderView(0)
TextView text = (TextView) header.findViewById(R.id.textView);
136
Francois Dermu

Voici comment je l'ai fait avec ButterKnife et cela fonctionne pour moi.

protected static class HeaderViewHolder {

    @BindView(R.id.button)
    Button button;

    HeaderViewHolder(View view) {
        ButterKnife.bind(this, view);
    }
}

puis utilisez ce détenteur de vue comme ceci:

View header = navigationView.getHeaderView(0);
headerViewHolder = new HeaderViewHolder(header);
12
Wahib Ul Haq

Pour moi, c'était la même situation avec 23.1.0, après la mise à jour, l'exception de pointeur null devient. Dans ce cas, la NavigatorView ressemble à:

<Android.support.design.widget.NavigationView
  Android:id="@+id/navigation_view"
  Android:layout_height="match_parent"
  Android:layout_width="wrap_content"
  Android:layout_gravity="start"
  Android:fitsSystemWindows="true"
  app:headerLayout="@layout/nav_header"
  app:menu="@menu/menu_nav"/>

J'ai essayé la solution proposée par ianhanniballake mais cela ne fonctionne pas. Puis j'ai gonflé avec la phrase:

LayoutInflater.from(getContext()).inflate(R.layout.nav_header, mNavigationView);

Après cela, je peux trouver par id toutes les vues définies dans nav_heardlayout.

8
Campino
NavigationView navigationView = findViewById(R.id.your_nav_view);
View header = navigationView.getHeaderView(0);
TextView textUsername = header.findViewById(R.id.textView);
textUsername.setText("you text here ");
2
indrit saveta