web-dev-qa-db-fra.com

Prise en charge d'Android v23.1.0: rupture de la mise à jour de l'en-tête NavigationView

J'utilisais la bibliothèque de support v23.0.1 jusqu'à présent sans aucun problème. Maintenant, lorsque je passe à la nouvelle bibliothèque v23.1.0, je reçois un pointeur nul sur les widgets de la disposition des tiroirs.

mNavigationView = (NavigationView) findViewById(R.id.navigation_view);    
TextView username = (TextView) mNavigationView.findViewById(R.id.username_textView);
//       ^^^^^^^^ is now null when using new library
// which causes the following to fail
username.setText(mUser.getName());

mise en page d'activité

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity">

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">

    <include layout="@layout/toolbar" />

    ...

</LinearLayout>

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

</Android.support.v4.widget.DrawerLayout>

tiroir_header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:fresco="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="150dp"
Android:orientation="vertical">

   <TextView
    Android:id="@+id/username_textView"
    Android:layout_width="match_parent"
    Android:layout_height="0dp" />

    ...

</LinearLayout>

Changer simplement le fichier gradle pour utiliser l'ancienne version le fait fonctionner correctement instantanément, donc je ne pense pas qu'il y ait un problème horriblement faux avec mon code. J'ai vérifié les révisions dans la mise à jour et je n'ai rien vu qui puisse causer cela.

Cela affectera sûrement les autres aussi, des indices?

29
Breavyn

Avec la bibliothèque de conceptions v 23.1.0, la NavigationView fonctionne avec une RecyclerView.
De plus, la Header est maintenant un type de ligne. 

Cela signifie que l'en-tête ne peut pas être immédiatement disponible dans la hiérarchie de vues.
Cela peut poser problème si vous utilisez des méthodes telles que navigationView.findViewById(XXX) pour obtenir une vue à l'intérieur de l'en-tête.

Il y a un bug dans le Google Tracker

EDIT 12/10/2015: Bibliothèque de conception 23.1.1

La 23.1.1 introduit une nouvelle API permettant de récupérer les vues d’en-tête de NavigationView avec getHeaderView ()

AVANT LE 23.1.1

solution de contournement pour 23.1.0 peut être d'utiliser une addOnLayoutChangeListener. Quelque chose comme:

navigationView.addOnLayoutChangeListener( new View.OnLayoutChangeListener()
{
    @Override
    public void onLayoutChange( ... )
    {
        navigationView.removeOnLayoutChangeListener( this );

        View view = navigationView.findViewById( ... );
    }
} );

Une autre solution possible est:

  • supprimez l'attribut app:headerLayout du fichier XML, puis ajoutez l'en-tête par programme.

  • Gonflez l'en-têteView par programme.

Utilisez quelque chose comme ça:

View headerLayout = navigationView.inflateHeaderView(R.layout.navigation_header);
headerLayout.findViewById(xxx);
41
Gabriele Mariotti

Il semble que l'attachement de la vue d'en-tête au tiroir de navigation à l'aide de xml est actuellement endommagé. La solution consiste à gonfler et attacher la vue manuellement.

présentation de l'activité

<Android.support.design.widget.NavigationView
    Android:id="@+id/navigation_view"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    Android:fitsSystemWindows="true"
    app:headerLayout="@layout/drawer_header" <!-- remove this line -->
    app:menu="@menu/drawer_items" />

Puis, dans votre code, gonflez et attachez l'en-tête en procédant comme suit.

NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);
View drawerHeader = navigationView.inflateHeaderView(R.layout.drawer_header);

TextView username = (TextView) drawerHeader.findViewById(R.id.username_textView);
11
Breavyn

dans la nouvelle NavigationView l'en-tête est maintenant un type de ligne de RecyclerView afin de permettre à vous ou à quiconque de trouver la view dans sa id, vous devrez contourner le problème et utiliser addOnLayoutChangeListener écouteur, puis vous pourrez trouver la view quelque part mais Android soit comme moi !. 

0
k0sh

J'ai mis à jour les outils de compilation à partir d'Android sdk manager, puis 23.1.0 fonctionne également très bien pour moi. 

J'utilise

buildToolsVersion "23.0.2"

avant cela, il était 23.0.1. 

et il n'y a pas besoin d'utiliser 

(View)navigationView.findViewById(R.id.idOfViewFromHeaderView);

Dans votre activité, vous pouvez utiliser directement 

(View)findViewById(R.id.idOfViewFromHeaderView);
0
Muhammad Adil
0
xushao