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

В моем NavigationView у меня есть макет заголовка с id 'viewId' с активными кнопками. Чтобы настроить эти кнопки, я делаю следующее в действии onPostCreate:

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

В новой библиотеке поддержки android поддержки (23.1.0) представление не может быть найдено, оно возвращает null. С предыдущими версиями он работал хорошо. Это ошибка, или я использую эту функцию неправильно? Если да, как получить доступ к макету заголовка и добавить к нему поведение?

Ответ 1

Версия 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() on что:

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

Пока вы не перейдете к 23.1.1.

Ответ 2

Теперь с выпуском библиотеки поддержки дизайна 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);

Ответ 3

Для меня это была та же ситуация с 23.1.0, после обновления стало исключение null-указателя. В этом случае 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.

Ответ 4

Вот как я это сделал, используя 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);