NavigationView макет заголовка get / find


171

У своєму NavigationView у мене макет заголовка з id 'viewId' з активними кнопками. Щоб налаштувати ці кнопки, я виконую наступні дії в діяльності onPostCreate:

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

З новою версією бібліотеки підтримки для Android ( 23.1.0 ) подання неможливо знайти, він повертається до нуля. З попередніми версіями він добре працював. Це помилка чи я неправильно використовую цю функцію? Якщо так, то як отримати доступ до макета заголовка та додати до нього поведінку?

Відповіді:


429

Версія 23.1.0 переходить NavigationViewна використання RecyclerView(а не попереднього ListView), і заголовок додається як один з цих елементів. Це означає, що він не доступний для дзвінків миттєво findViewById()- потрібен пропуск макета, перш ніж його прикріпити до NavigationView.

Для версії 23.1.1 Бібліотеки підтримки тепер ви можете отримати посилання на перегляд заголовка, використовуючи getHeaderView():

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

Це має перевагу в роботі над заголовками, доданими через XML та за допомогою коду.

Якщо ви все ще використовуєте 23.1.0 відповідно до відповідної помилки , ви можете надути заголовок у коді та використовувати findViewById()для цього:

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

Поки ви не переходите до 23.1.1.


1
Дякуємо за швидку допомогу, будемо використовувати вирішення. Маючи присвячений метод, здається, шлях у майбутньому, сподіваємось, він буде його мати у майбутніх випусках.
Хусрав

2
@AlexanderFarber - код, який я опублікував, працює назад до API 7
ianhanniballake

4
Я вважаю за краще знижувати губи. Представляти помилку - це як підпис від Google. Якщо в новій версії є помилка, то Google випустила нову версію
BamsBamx

1
@GFPF - коли ви телефонуєте inflateHeaderView, він приєднує Вигляд для вас у правильному шарі в RecyclerViewправильному батьківському шарі - те, що ви не можете зробити зовнішньо NavigationView.
ianhanniballake

1
@RmK - дякую, я оновив відповідь, щоб відобразити нові API, додані в 23.1.1, щоб отримати заголовки, додані через XML (так як попереднє вирішення працювало лише над заголовками, доданими за допомогою коду).
ianhanniballake

142

Тепер з випуском 23.1.1 бібліотеки підтримки дизайну ви можете користуватися

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

Ви також можете використовувати, navigationView.getHeaderCount()якщо у вас є більше 1 заголовка з будь-якої причини.
Франсуа Дерму

13

Ось як я це робив за допомогою, ButterKnifeі це працює для мене.

protected static class HeaderViewHolder {

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

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

а потім скористайтеся цим власником перегляду так:

View header = navigationView.getHeaderView(0);
headerViewHolder = new HeaderViewHolder(header);

2
Це ідеально, коли ви хочете видалити Перегляд пов’язаної логіки зі своєї діяльності. Чудова ідея!
amouly

2
Її чудово співпрацюють з ButterKnife, дякую брате.
Раджеш Надді,

8

Для мене така ж ситуація була з 23.1.0, після оновлення стає винятком нульового вказівника. У цьому випадку NavigatorViewвиглядають так:

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

Я спробував пропозицію рішення від ianhanniballake, але це не працює. Тоді я завищив речення:

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

Після цього я можу знайти за id усі перегляди, визначені у nav_heardмакеті.


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

Привіт і ласкаво просимо до Stack Overflow! Будь ласка, додайте текст, який пояснює, як це вирішує питання, задане вище. Дякую!
Джонатан

0

У Котліні @Francois Dermu код буде подібний

val navigationView : NavigationView = findViewById(R.id.your_nav_view_id);
val header = navigationView.getHeaderView(0)
val textView = header.findViewById<TextView>(R.id.textView)

0

Версія Котліна.

val navView: NavigationView = findViewById(R.id.nav_view)       
// set User Name
val headerView: View = navView.getHeaderView(0)
headerView.txtUserName.text = "User Name Goes here"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.