ActionView 设置为支持 NavigationView 不显示的项目

ActionView set to an item in support NavigationView not showing

我在导航抽屉中使用支持 NavigationView 来显示项目菜单。

<android.support.design.widget.NavigationView
    android:id="@+id/drawer_navigation"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@drawable/drawable_background"
    app:headerLayout="@layout/drawer_header"
    app:itemBackground="@drawable/drawer_item_background"
    app:itemIconTint="@color/drawer_item"
    app:itemTextColor="@color/drawer_item"
    app:menu="@menu/drawer"
    app:theme="@style/Text.DrawerItem"/>

我想在菜单项旁边显示连接请求计数器。

我试过像这样在 XML 菜单定义中设置 actionLayout

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

  <group android:checkableBehavior="single">
    ...
    <item
        android:id="@+id/navigation_requests"
        android:icon="@drawable/ic_swap_horiz_24dp"
        android:title="@string/connect_menu_connection_requests"
        app:actionLayout="@layout/connection_request_counter"
        app:showAsAction="always"/>
    ...
  </group>
</menu>

ActionView 的布局connection_request_counter.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="match_parent"
      android:gravity="center_vertical"
      android:textColor="@color/brand_blue"
      android:text="5"/>

但此时我看不到项目旁边的数字 5。

我也尝试过以编程方式设置 ActionLayout:

MenuItemCompat.setActionView(mMenu.findItem(R.id.navigation_requests), R.layout.connection_request_counter);

但还是没有运气。

我可以像这样获取对 TextView 的引用

final TextView connectionRequestCounterView
            = (TextView) MenuItemCompat.getActionView(mMenu.findItem(R.id.navigation_requests));

这实际上 returns 一个 TextView 实例,但即使我为它设置了文本,我也看不到布局中的任何内容。这可能与我正在设计菜单项的样式有关吗? (我设置了菜单项的文本颜色、色调和背景)

这是我的风格:

<style name="Text.DrawerItem">
    <item name="android:textColor">@color/text_color_dark_grey</item>
    <item name="android:textSize">@dimen/text_size_default</item>
    <item name="android:clickable">false</item>
    <item name="android:textColorLink">@color/text_color_dark_grey</item>
    <item name="fontPath">@string/font_aller_light</item>
    <!--<item name="android:background">@color/background_activity_default</item>-->
    <!--<item name="background">@color/background_activity_default</item>-->
</style>

drawer_item_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <!--To override the default grey background for selected item-->
  <item android:drawable="@android:color/transparent" android:state_checked="true"/>
  <item android:drawable="@android:color/transparent"/>
</selector>

drawer_drawablbe.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <item>
    <shape android:shape="rectangle">
        <solid android:color="@color/background_activity_default"/>
    </shape>
  </item>
  <item
    android:bottom="24dp"
    android:left="16dp">
      <bitmap
        android:gravity="left|bottom"
        android:src="@drawable/my_drawer_logo"/>
  </item>

</layer-list>

其中 @drawable/my_drawer_logo 是不同密度的 PNG。

为什么我看不到操作视图还有其他想法吗?

我可以很容易地更改计数器的文本。但是,我使用的文本视图在 LinearLayout 内,它也有一个 android:id(我在没有 LinearLayout 的情况下尝试过没有问题):

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/textCounter"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:textColor="@color/colorPrimary"
        android:text="5"/>
</LinearLayout>

鉴于此,我可以使用以下内容查看、访问和修改主 activity 中的文本视图:

TextView countText = (TextView)findViewById(R.id.textCounter);

countText.setText("6");

当然,我使用了一个简单的方法来计算这个值,只是将它设置为值“6”,但是,我不知道你的计数器结构实际上是什么样子的,那些不是你问题的主要关注点。

您能否查看柜台号码的问题仍然是个谜。看看我上面的问题,我们也会敲定那个要素。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
}

我最终找到了导致问题的原因。 要使 NavigationView 与操作视图一起正常工作,您必须使用 AppCompat 支持库版本 23.1

所以不用

compile 'com.android.support:appcompat-v7:22.3.0'

我不得不更新到

compile 'com.android.support:appcompat-v7:23.1.1'

这使得导航抽屉的导航视图中的技巧和操作视图开始正确显示,完全符合我的要求。


更新到新的 AppCompat 版本时,我遇到了更多问题,例如 ClassNotFoundException 在启动应用程序时出现,我通过将 所有 com.android.support 库更新到最新版本:

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:support-annotations:23.1.1'
...

然后我仍然在我的 header 布局中得到 NullPointerException 设置为 NavigationView。如果您在代码中设置 app:headerLayout="@layout/drawer_header" 或类似设置,在 AppCompat 版本 22 中,可以通过 findViewById() 获取 header 视图。

AppCompat 版本 23 对包括 header 视图在内的所有项目使用 RecyclerView,因此获取其视图引用的方法如下:

 mHeaderView = navigationView.getHeaderView(HEADER_INDEX);

如果您不添加多个 header,则 HEADER_INDEX 很可能为 0。