NavigationView获取/查找标题布局


175

在我的NavigationView中,我有一个带有活动按钮的ID为'viewId'的标题布局。要设置这些按钮,我将在活动中执行以下操作onPostCreate

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

使用新版本的android支持库(23.1.0),找不到视图,它返回null。使用以前的版本,效果很好。是错误还是我使用此功能有误?如果是这样,如何访问标题布局并为其添加行为?

Answers:


433

版本23.1.0切换NavigationView为使用RecyclerView(而不是上一个ListView),并且标头作为这些元素之一添加。这意味着它不能立即调用findViewById()-在将布局附加到之前需要布局传递NavigationView

对于支持库的23.1.1版本,您现在可以使用getHeaderView()以下内容获取对标题视图的引用:

View headerLayout = navigationView.getHeaderView(0); // 0-index header

这具有处理通过XML和通过代码添加的标头的优势。

如果仍在使用23.1.0,则根据相关的bug,可以在代码中填充标头并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

3
@AlexanderFarber-我发布的代码可以追溯到API 7
ianhanniballake 2015年

4
我更喜欢降级库。引入错误就像来自Google的签名一样。如果新版本存在错误,则Google发布了该新版本
BamsBamx 2015年

1
@GFPF-调用时inflateHeaderView,它将为您附加RecyclerView正确的父视图到正确的图层中,这是您无法从外部进行的NavigationView
ianhanniballake

1
@RmK-谢谢,我已经做出更新以反映在23.1.1中添加的新API,以检索通过XML添加的标头(因为以前的解决方法仅适用于通过代码添加的标头)。
ianhanniballake

144

现在,在设计支持库的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()出于任何原因您有多个标头,也可以使用。
弗朗索瓦·德穆

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

2
它非常适合ButterKnife,谢谢兄弟。
Rajesh Naddy18年

8

对我来说,与23.1.0情况相同,在更新后,空指针异常变为。在这种情况下,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_heardlayout中定义的所有视图。


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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.