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)では、ビューが見つからず、nullを返します。以前のバージョンではうまくいきました。それはバグですか、それともこの機能を間違って使用していますか?もしそうなら、どのようにヘッダーレイアウトにアクセスし、それに動作を追加するのですか?

回答:


429

バージョン23.1.0 NavigationViewRecyclerView(以前のものではなく)を使用するように切り替えListView、ヘッダーがそれらの要素の1つとして追加されます。これは、すぐに呼び出すことができないことを意味します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、ビューはの正しいレイヤーRecyclerViewの正しい親にアタッチされますNavigationView。外部からは実行できないものです。
ianhanniballake 2015年

1
@RmK-おかげで、XML経由で追加されたヘッダーを取得するために23.1.1で追加された新しいAPIを反映するように回答を更新しました(以前の回避策はコード経由で追加されたヘッダーでしか機能しなかったため)。
ianhanniballake 2015年

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 2015年

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 2017年

2
バターナイフとの完全な連携は、兄弟に感謝します。
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_heardlayoutで定義されたすべてのビューを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へようこそ!上記の質問を解決する方法を説明するテキストを追加してください。ありがとう!
ジョナサン

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

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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.