NavigationView Get / find układ nagłówka

171

W moim NavigationView mam układ nagłówka z identyfikatorem „viewId” z aktywnymi przyciskami. Aby skonfigurować te przyciski, wykonuję następujące czynności onPostCreate:

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

W nowej wersji biblioteki obsługi systemu Android ( 23.1.0 ) nie można znaleźć widoku, zwraca on null. Z poprzednimi wersjami działało dobrze. Czy to błąd, czy też źle używam tej funkcji? Jeśli tak, jak uzyskać dostęp do układu nagłówka i dodać do niego zachowanie?

khusrav
źródło

Odpowiedzi:

429

Wersja 23.1.0 przełącza się NavigationViewna używanie a RecyclerView(zamiast poprzedniej ListView), a nagłówek jest dodawany jako jeden z tych elementów. Oznacza to, że nie można go natychmiast wywołać findViewById()- wymagane jest przejście układu, zanim zostanie dołączone do NavigationView.

W przypadku wersji 23.1.1 biblioteki obsługi można teraz uzyskać odniesienie do widoku nagłówka za pomocą getHeaderView():

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

Ma to tę zaletę, że pracuje nad nagłówkami dodanymi za pomocą XML i kodu.

Jeśli nadal używasz 23.1.0, zgodnie z powiązanym błędem , możesz zawyżać nagłówek w kodzie i użyć findViewById()na tym:

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

Dopóki nie przejdziesz do 23.1.1.

ianhanniballake
źródło
1
Dzięki za szybką pomoc, zastosuję obejście. Posiadanie dedykowanej metody wydaje się być właściwą drogą, mam nadzieję, że będzie to możliwe w przyszłych wydaniach.
khusrav
2
@AlexanderFarber - kod, który opublikowałem, działa z powrotem do API 7
ianhanniballake
4
Wolę obniżyć wersję libs. Wprowadzenie błędu jest jak podpis od Google. Jeśli nowa wersja zawiera błąd, Google wydało tę nową wersję
BamsBamx
1
@GFPF - kiedy wywołujesz inflateHeaderView, dołącza on dla ciebie Widok we właściwej warstwie RecyclerViewz właściwym rodzicem - coś, czego nie możesz zrobić zewnętrznie NavigationView.
ianhanniballake
1
@RmK - dzięki, zaktualizowałem odpowiedź, aby odzwierciedlić nowe interfejsy API dodane w 23.1.1, aby pobrać nagłówki dodane przez XML (ponieważ poprzednie obejście działało tylko na nagłówkach dodanych za pomocą kodu).
ianhanniballake
142

Teraz, w wersji 23.1.1 biblioteki obsługi projektowania, możesz używać

NavigationView navigationView = (NavigationView) findViewById(R.id.your_nav_view_id);
View header = navigationView.getHeaderView(0)
TextView text = (TextView) header.findViewById(R.id.textView);
Francois Dermu
źródło
Możesz również użyć, navigationView.getHeaderCount()jeśli masz więcej niż 1 nagłówek z dowolnego powodu.
Francois Dermu
13

Tak to zrobiłem ButterKnifei działa na mnie.

protected static class HeaderViewHolder {

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

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

a następnie użyj tego uchwytu widoku w następujący sposób:

View header = navigationView.getHeaderView(0);
headerViewHolder = new HeaderViewHolder(header);
Wahib Ul Haq
źródło
2
Jest to idealne rozwiązanie, gdy chcesz usunąć powiązaną logikę widoku ze swojej aktywności. Świetny pomysł!
amouly
2
Doskonale współpracuje z ButterKnife, dzięki bracie.
Rajesh Naddy
8

Dla mnie była to ta sama sytuacja z 23.1.0, po aktualizacji stał się wyjątek zerowego wskaźnika. W tym przypadku NavigatorViewwygląda to tak:

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

Wypróbowałem propozycję rozwiązania autorstwa ianhanniballake, ale nie działa. Potem nadmuchałem zdaniem:

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

Potem mogę znaleźć według id wszystkie widoki zdefiniowane w nav_heardukładzie.

Campino
źródło
3
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 ");
indrit saveta
źródło
Cześć i witaj w Stack Overflow! Dodaj tekst wyjaśniający, jak to rozwiązuje powyższe pytanie. Dzięki!
Jonathan
0

W Kotlin @Francois Dermu kod będzie podobny

val navigationView : NavigationView = findViewById(R.id.your_nav_view_id);
val header = navigationView.getHeaderView(0)
val textView = header.findViewById<TextView>(R.id.textView)
Alex
źródło
0

Wersja Kotlin.

val navView: NavigationView = findViewById(R.id.nav_view)       
// set User Name
val headerView: View = navView.getHeaderView(0)
headerView.txtUserName.text = "User Name Goes here"
Qadir Hussain
źródło