目录

NavigationView 如何查询头部的 View

目录

在使用 Butter Knife 注入 NavigationView 内部元素的时候发生了 NPE 问题,搜索相关问题的解答终于明白了具体的原因和问题解决办法。

实际上,在 23.1.0 版本之后 NavigationView 的实现使用了 RecyclerView 代替 ListView,这使得直接调用 findViewById() 方法就无法顺利获取头部内部的 View,而 Butter Kinfe 本身是对 findViewById() 的包装,自然也就无法顺利的注入控件引用了。 经过查看源代码发现了 NavigationView 提供了一个方法 getHeaderView(),可以传入整数来获取对应下标的 HeaderLayout。一般来说 HeaderLayout 的结构都很简单,大都类似如下形式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="@dimen/nav_header_height"
  android:background="@drawable/side_nav_bar"
  android:gravity="bottom"
  android:orientation="vertical"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  android:theme="@style/ThemeOverlay.AppCompat.Dark">

	<ImageView
	  android:id="@+id/imageView"
	  android:layout_width="wrap_content"
	  android:layout_height="wrap_content"
	  android:paddingTop="@dimen/nav_header_vertical_spacing"
	  app:srcCompat="@mipmap/ic_launcher_round" />

	<TextView
	  android:id="@+id/text_view_username"
	  android:layout_width="match_parent"
	  android:layout_height="wrap_content"
	  android:paddingTop="@dimen/nav_header_vertical_spacing"
	  android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
	
	<TextView
	  android:id="@+id/text_view_email"
	  android:layout_width="wrap_content"
	  android:layout_height="wrap_content" />

</LinearLayout>

这样的 header 实际是把上述 xml 代码中的 LinearLayout 整体作为 HeaderLayout 添加到 NavigationView 中,所容易只要使用 getHeaderView(0) 就能获取 LinearLayout 的引用。然后想要获取内部的两个 TextView 就很简单了,只要使用 ViewfindViewById 方法即可。

参考: NavigationView get/find header layout