NavigationView get / find 헤더 레이아웃


171

내 NavigationView에는 활성 버튼이있는 ID가 'viewId'인 헤더 레이아웃이 있습니다. 해당 버튼을 설정하려면 활동에서 다음을 수행하십시오 onPostCreate.

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

새로운 버전의 안드로이드 지원 라이브러리 ( 23.1.0 )에서는 뷰를 찾을 수 없으며 null을 반환합니다. 이전 버전에서는 잘 작동했습니다. 버그입니까, 아니면이 기능을 잘못 사용하고 있습니까? 그렇다면 헤더 레이아웃에 액세스하여 동작을 추가하는 방법은 무엇입니까?

답변:


429

버전 23.1.0 NavigationViewRecyclerView(이전이 아닌) 을 사용하도록 전환 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
신속한 도움을 주셔서 감사합니다. 해결 방법을 사용합니다. 전용 방법을 사용하는 것이 좋을 것으로 예상되므로 향후 릴리스에서이를 사용할 수 있기를 바랍니다.
khusrav

2
@AlexanderFarber-내가 게시 한 코드는 API 7로 다시 작동합니다.
ianhanniballake

4
라이브러리를 다운 그레이드하는 것을 선호합니다. 버그를 소개하는 것은 Google의 서명과 같습니다. 새로운 버전의 버그이있는 경우, Google은 새 버전 출시
BamsBamx

1
@GFPF-호출 하면 외부에서 할 수없는 올바른 부모 inflateHeaderView가있는 올바른 레이어의 View가 연결 RecyclerView됩니다 NavigationView.
ianhanniballake 4

1
@ RmK-감사합니다 .23.1.1에 추가 된 새로운 API를 반영하여 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()어떤 이유로 든 헤더가 두 개 이상인 경우 에도 사용할 수 있습니다 .
Francois Dermu

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
활동에서 View 관련 논리를 제거하려는 경우에 적합합니다. 좋은 생각이야!
amouly

2
ButterKnife와 완벽하게 작동합니다.
Rajesh Naddy

8

나에게 그것은 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);

그 후, nav_heard레이아웃으로 정의 된 모든보기를 id로 찾을 수 있습니다 .


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에 오신 것을 환영합니다! 위의 질문을 해결하는 방법을 설명하는 텍스트를 추가하십시오. 감사!
Jonathan

0

Kotlin에서 @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"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.