【问题标题】:Android support v23.1.0 update breaks NavigationView get/find headerAndroid 支持 v23.1.0 更新中断 NavigationView 获取/查找标头
【发布时间】:2015-10-16 01:55:03
【问题描述】:

到目前为止,我一直在使用 v23.0.1 支持库,没有任何问题。现在,当我切换到新的 v23.1.0 库时,我在抽屉布局中的小部件上得到一个空指针。

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,没有看到任何我认为会导致此问题的内容。

这肯定也会影响到其他人,有什么线索吗?

【问题讨论】:

标签: android android-support-library android-design-library android-navigationview android-support-design


【解决方案1】:

使用设计库 v 23.1.0NavigationViewRecyclerView 一起使用。
Header 现在也是一种行。

这意味着标题不能立即在视图层次结构中可用
如果您使用 navigationView.findViewById(XXX) 之类的方法来获取标题内的视图,则可能会导致问题。

Google Tracker 中有一个错误。

编辑 2015 年 12 月 10 日:设计库 23.1.1

23.1.1 引入了一个新的 API,用于检索带有 getHeaderView() 的 NavigationView 的标题视图

23.1.1 之前

解决方法 fot 23.1.0 可以使用 addOnLayoutChangeListener。类似的东西:

navigationView.addOnLayoutChangeListener( new View.OnLayoutChangeListener()
{
    @Override
    public void onLayoutChange( ... )
    {
        navigationView.removeOnLayoutChangeListener( this );

        View view = navigationView.findViewById( ... );
    }
} );

另一种可能的解决方法是:

  • 从 xml 中删除 app:headerLayout 属性,然后以编程方式添加标头。

  • 以编程方式扩展 headerView。

使用这样的东西:

View headerLayout = navigationView.inflateHeaderView(R.layout.navigation_header);
headerLayout.findViewById(xxx);

【讨论】:

  • NavigationViewaddHeaderView() inflateHeaderView()removeHeaderView() 方法。也许他们应该给我们一个getHeaderView() 方法,该方法在从 xml 创建时也有效。
  • 好答案。这正是上周 23.1 发布时我让标题工作的方式。我对 23.1 中的其他一些修复非常兴奋,但后来我遇到了这个新问题。目前解决它的唯一方法是在代码中膨胀。
  • @ColinGillespie 先生,inflateHeaderView() 已经将整数资源作为参数,它返回 View 对象。现在使用这个View 对象,我们可以找到我们的内部视图或控件并将其保存以供将来使用。例如,更新NavigationView 中的个人资料图片..
  • @ChintanSoni 是的,我发布了这个;从这个答案和我在下面的答案中可以看出。关键是能够访问使用 app:headerLayout="" 选项纯粹从 xml 添加的标题视图。
【解决方案2】:

目前使用 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);

【讨论】:

  • 根据新库投票认为有用
【解决方案3】:

在新的NavigationView 中,标题现在是RecyclerView 的行类型,以便您或任何人通过其id 找到view,您需要解决它并使用addOnLayoutChangeListener 侦听器然后你可以找到view 我知道它应该记录在某个地方但是android就像meh!。

【讨论】:

  • 好吧,这是有道理的。使用这种解决方法还是我描述的方法更可取?还是真的不重要?
  • 我还没有尝试过您的解决方法,正如您所说的 xml 当前已损坏,但这似乎可以解决它。所以它们都应该是可以接受的,因为现在更多的是个人选择,无论是从 xml 定义还是以编程方式定义。
【解决方案4】:

这是 23.1.0 的错误

23.1.1 已修复

https://plus.google.com/+AndroidDevelopers/posts/ebXLByBiEBU

【讨论】:

    【解决方案5】:

    我已经从 Android sdk 管理器更新了构建工具,然后 23.1.0 对我来说也可以正常工作。

    我正在使用

    buildToolsVersion "23.0.2"
    

    在此之前是 23.0.1。

    而且没有必要使用

    (View)navigationView.findViewById(R.id.idOfViewFromHeaderView);
    

    在你的activity中你可以直接使用

    (View)findViewById(R.id.idOfViewFromHeaderView);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 2015-10-19
      • 2013-07-26
      相关资源
      最近更新 更多