NavigationView获取/查找标题布局

184

在我的NavigationView中,我有一个带有id“viewId”的头布局和活动按钮。为了设置这些按钮,我在activity的 onPostCreate 中执行以下操作:

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

使用新版 Android 支持库(23.1.0),找不到视图,返回 null。在之前的版本中,它能够很好地工作。这是一个 bug 吗?还是我使用了错误的功能?如果是 bug,如何访问标题布局并为其添加行为?

10个回答

456

版本23.1.0将NavigationView切换到使用RecyclerView(而不是以前的ListView),并将标题添加为这些元素之一。这意味着在它附加到NavigationView之前需要进行布局处理,才能立即调用findViewById()

对于支持库的版本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版本。


3
@AlexanderFarber - 我发布的代码可以在 API 7 及以上版本中运行。 - ianhanniballake
4
我愿意降级库。引入一个 bug 就像是来自 Google 的签名。如果新版本有 bug,那么就是 Google 发布了这个新版本。 - BamsBamx
1
@GFPF - 当你调用inflateHeaderView时,它会为你在RecyclerView中的正确层级和正确父级上附加视图 - 这是你无法在NavigationView外部完成的。 - ianhanniballake
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - RmK
1
@RmK - 谢谢,我已经更新了答案以反映在23.1.1中添加的新API,以检索通过XML添加的标头(因为先前的解决方法仅适用于通过代码添加的标头)。 - ianhanniballake
显示剩余5条评论

152

现在随着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

14

这是我使用 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
这是在你想要从你的Activity中移除与View相关的逻辑时的完美选择。太棒了! - amouly
2
它与ButterKnife完美地配合,谢谢兄弟。 - Rajesh Naddy

9

对我来说,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_header布局中定义的所有视图。


5
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 ")

4
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

1

在Java中对我有效

   navigationView = findViewById(R.id.nav_view);
    View viewHeader = navigationView.getHeaderView(0);
    ((TextView)viewHeader.findViewById(R.id.tv_name)).setText(preferences.getString(MyConstant.NAME,"n/a"));

1

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"

1

在 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

以下是如何在抽屉中更改用户名的方法。

NavigationView mNavigationView = findViewById(R.id.nav_view);
View mHeaderView = mNavigationView.getHeaderView(0);
TextView usernameTextview = mHeaderView.findViewById(R.id.drawer_email_textField);
Bundle b = getIntent().getExtras();
String username = b.getString("email");
usernameTextview.setText(username);

这对我有效


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接