これまでv23.0.1サポートライブラリを問題なく使用してきました。新しいv23.1.0ライブラリに切り替えると、ドロワーレイアウトのウィジェットにnullポインターが表示されます。
mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
TextView username = (TextView) mNavigationView.findViewById(R.id.username_textView);
// ^^^^^^^^ is now null when using new library
// which causes the following to fail
username.setText(mUser.getName());
アクティビティレイアウト
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<include layout="@layout/toolbar" />
...
</LinearLayout>
<Android.support.design.widget.NavigationView
Android:id="@+id/navigation_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer_items" />
</Android.support.v4.widget.DrawerLayout>
drawer_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:fresco="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="150dp"
Android:orientation="vertical">
<TextView
Android:id="@+id/username_textView"
Android:layout_width="match_parent"
Android:layout_height="0dp" />
...
</LinearLayout>
古いバージョンを使用するようにgradleファイルを変更するだけですぐに正常に機能するので、コードにひどい問題はないと思います。私はアップデートで revisions をチェックアウトしましたが、これを引き起こすと思われるものは何も見つかりませんでした。
確かにこれは他の人にも影響を及ぼしますが、手がかりはありますか?
設計ライブラリv 23.1.0では、NavigationView
はRecyclerView
で機能します。
また、Header
は一種の行になりました。
これは、ヘッダーがビュー階層ですぐに使用できないことを意味します。navigationView.findViewById(XXX)
などのメソッドを使用してヘッダー内のビューを取得すると、問題が発生する可能性があります。
Google Tracker にバグがあります。
EDIT 12/10/2015:デザインライブラリ23.1.1
23.1.1では、 getHeaderView() を使用してNavigationViewのヘッダービューを取得するための新しいAPIが導入されています
23.1.1より前
回避策fot 23.1.0はaddOnLayoutChangeListener
を使用することができます。次のようなもの:
navigationView.addOnLayoutChangeListener( new View.OnLayoutChangeListener()
{
@Override
public void onLayoutChange( ... )
{
navigationView.removeOnLayoutChangeListener( this );
View view = navigationView.findViewById( ... );
}
} );
別の可能な回避策は次のとおりです:
app:headerLayout
属性をxmlから削除し、プログラムでヘッダーを追加します。
プログラムでheaderViewを拡張します。
このようなものを使用してください:
View headerLayout = navigationView.inflateHeaderView(R.layout.navigation_header);
headerLayout.findViewById(xxx);
ヘッダービューをxmlを使用してナビゲーションドロワーにアタッチすることは現在壊れています。解決策は、ビューを手動でインフレートしてアタッチすることです。
アクティビティレイアウト
<Android.support.design.widget.NavigationView
Android:id="@+id/navigation_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:headerLayout="@layout/drawer_header" <!-- remove this line -->
app:menu="@menu/drawer_items" />
次に、コードで次のようにしてインフレートし、ヘッダーを添付します。
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);
View drawerHeader = navigationView.inflateHeaderView(R.layout.drawer_header);
TextView username = (TextView) drawerHeader.findViewById(R.id.username_textView);
新しいNavigationView
では、ヘッダーはRecyclerView
の行タイプになりました。これにより、あなたまたは誰もが必要なview
によってid
を見つけることができます。それを回避し、addOnLayoutChangeListener
リスナーを使用すると、view
を見つけることができます。どこかに文書化する必要があることを知っていますが、Android meh!のようにしてください。
Android sdk managerからビルドツールを更新したので、23.1.0も正常に動作しています。
使ってます
buildToolsVersion "23.0.2"
これ以前は23.0.1でした。
使用する必要はありません
(View)navigationView.findViewById(R.id.idOfViewFromHeaderView);
あなたの活動では直接使用できます
(View)findViewById(R.id.idOfViewFromHeaderView);