29

Ho utilizzato la libreria di supporto v23.0.1 fino ad ora senza problemi. Ora, quando passo alla nuova libreria v23.1.0, ottengo un puntatore nullo sui widget nel layout del cassetto.interruzioni di aggiornamento del supporto Android v23.1.0 interruzioni NavigationView get/find header

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

layout di attività

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

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

semplicemente modificando il file Gradle di utilizzare la versione precedente lo fa funzionare bene immediatamente in modo non lo faccio penso che ci sia qualcosa di terribilmente sbagliato nel mio codice. Ho verificato il revisions nell'aggiornamento e non ho visto nulla che avrei pensato di causare questo.

Sicuramente questo influenzerà anche gli altri, qualche indizio?

+0

hanno controllato il numero di bambino dentro vista di navigazione? è possibile utilizzare getChildCount() –

+3

Controllare https://code.google.com/p/android/issues/detail?id=190226 –

+0

Lo stesso problema qui – Sheychan

risposta

40

Con la libreria di progettazione v 23.1.0 il NavigationView funziona con un RecyclerView.
Anche lo Header è ora un tipo di riga.

Significa che l'intestazione potrebbe non essere immediatamente disponibile nella gerarchia di viste.
Può causare problemi se si utilizzano metodi come navigationView.findViewById(XXX) per ottenere una vista all'interno dell'intestazione.

C'è un errore nello Google Tracker.

EDIT 2015/12/10: Design Library 23.1.1

Il 23.1.1 introduce una nuova API per il recupero di una vista di intestazione per NavigationView con getHeaderView()

PRIMA 23.1.1

soluzione per 23.1.0 può essere quello di utilizzare un addOnLayoutChangeListener. Somenthing come:

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

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

Un'altra possibile soluzione sono:

  • rimuovere l'attributo app:headerLayout dal XML, e quindi aggiungere l'intestazione programatically.

  • Gonfiare l'intestazioneView a livello di programmazione.

Usa somenthing come questo:

View headerLayout = navigationView.inflateHeaderView(R.layout.navigation_header); 
headerLayout.findViewById(xxx); 
+4

'NavigationView' ha i metodi' addHeaderView() '' inflateHeaderView() 'e' removeHeaderView() '. Forse dovrebbero darci anche un metodo 'getHeaderView()' che funziona quando si crea da xml. – Breavyn

+0

Buona risposta. Questo è esattamente il modo in cui ho ottenuto le intestazioni la scorsa settimana quando è uscito il 23.1. Ero così entusiasta di alcune delle altre correzioni in 23.1, ma poi mi sono imbattuto in questo nuovo problema. L'unico modo per aggirarlo ora è gonfiare il codice. – hungryghost

+0

@ColinGillespie Signore, 'inflateHeaderView()' sta già prendendo la risorsa intera come argomento e restituisce l'oggetto 'View'. Ora usando questo oggetto 'View', possiamo trovare le nostre viste o controlli interni e salvarlo per uso futuro. Ad esempio, aggiorna l'immagine del profilo in' NavigationView' .. –

11

Appare allegando la vista dell'intestazione al cassetto di navigazione utilizzando xml attualmente danneggiato. La soluzione è gonfiare e collegare la vista manualmente.

layout di attività

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

Poi, nel tuo codice di gonfiare e fissare l'intestazione facendo quanto segue.

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

Votato per utile in base alla nuova libreria –

+0

grazie lavoro per me ... –

0

nel nuovo NavigationView di testa che ora è un tipo di riga di RecyclerView in modo per voi o per chiunque di trovare la view dal suo id dovrete aggirare e utilizzare addOnLayoutChangeListener ascoltatore e quindi è possibile trovare il view so che dovrebbe essere documentato da qualche parte, ma Android essere come meh !.

+0

Va bene, è logico. È preferibile utilizzare questa soluzione alternativa o quella che ho descritto? O non importa davvero? – Breavyn

+0

non ho ancora provato il tuo workaround tho, come hai affermato che il xml è correntemente rotto ma questo sembra risolverlo. quindi entrambi dovrebbero essere accettabili in quanto è ora più una scelta personale, sia che la definiscano da xml o programmaticamente. – k0sh

0

Ho aggiornato strumenti di compilazione da Anche il gestore di sdk per Android, quindi il 23.1.0 funziona bene per me.

Sto usando

buildToolsVersion "23.0.2" 

prima di questo era 23.0.1.

e non v'è alcuna necessità di utilizzare

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

Nella vostra attività è possibile utilizzare direttamente

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