首页 > 解决方案 > Android 工具栏和菜单让我发疯

问题描述

我在 Activity xml 文件中创建了一个工具栏(为简洁起见)

<Toolbar
    android:id="@+id/mytoolbar"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:title="@string/password_manager"
    android:logo="@android:drawable/ic_menu_view"
    android:background="@color/colorPrimary"/>

我确实尝试了其他风格的工具栏 - androidx.appcompat...、...appbar.MaterialToolbar,以及我最常遇到的 android.support.v7.widget.Toolbar。这些使我的应用程序崩溃。

我制作了一个包含此内容的菜单 xml(为简洁起见):

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

    <item
        android:id="@+id/hmenu_createnew"
        android:checkable="false"
        android:enabled="true"
        android:title="@string/create_new"
        app:showAsAction="always" />

</menu>

在这一点上,一切看起来都很好。现在 - 我想动态控制菜单项。我添加了覆盖:

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    super.onPrepareOptionsMenu( menu );
    this.menu = menu;
    return true;
}

这就是令人沮丧的地方。未调用上述覆盖。我进行了大量搜索,遇到了一个建议更改 Activity 类声明的人。

他说,而不是“扩展活动”更改为“扩展 AppCompatActivity”

我检查了我的类声明,它已经AppCompat。一时兴起,我将其更改为活动。

通过此更改,我现在可以在调试器中看到我的覆盖被调用。耶!

但我的菜单无处可寻!

在我的 activity.class 中有这几行(为简洁起见):

protected void onCreate(Bundle savedInstanceState) {

        toolbar = (Toolbar) findViewById(R.id.mytoolbar);
        setActionBar( toolbar );
        toolbar.inflateMenu( R.menu.home_mainmenu );

}

由于这不再起作用,我删除了 toolbar.inflateMenu(),将其替换为 getMenuInflater() 并将其放入覆盖中,如下所示。

@Override
public boolean onCreateOptionsMenu (Menu menu) {
    super.onCreateOptionsMenu( menu );
    getMenuInflater().inflate( R.menu.home_mainmenu, menu );
    return false;
}

没有喜悦。

我也试过这个:

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    super.onPrepareOptionsMenu( menu );
    getMenuInflater().inflate( R.menu.home_mainmenu, menu );
    this.menu = menu;
    return false;
}

仍然没有喜悦。

在上面的两个覆盖中,我还尝试将 getMenuInflater.... 替换为 toolbar.inflateMenu...

没有喜悦。

我想要的是一个带有右对齐标准按钮的常规工具栏,该按钮带有三个垂直点,单击时会显示一个菜单。

在这一点上我一无所知,所以让我提前对有解决方案的天使说声谢谢。

有没有人认为这是不必要的困难?......再次,TIA。

标签: androidandroid-studioandroid-layoutandroid-toolbarandroid-menu

解决方案


好吧,我最终确实弄明白了。重复一下,我正在使用这个库:

导入android.widget.Toolbar;

因为我想使用 Activity - 而不是 AppCompatActivity

所以 xml 声明如下所示:<Toolbar ..... />

因为我们使用的是 Toolbar,所以我们必须移除 Android 提供给我们的默认 ActionBar。这需要编辑应用清单。任何你发现“AppTheme.ActionBar”更改为“AppTheme.NoActionBar”的地方

在java类中我有这个:

protected void onCreate(Bundle savedInstanceState) {
        Toolbar toolbar = findViewById(R.id.mytoolbar);
        setActionBar( toolbar );
}

请注意使用“setActionBar”而不是“setSupportActionBar”。那是对的。

然后是(终于!)正确编码的覆盖,无论您选择什么导入库,它都可能对任何人有用:

    @Override
    public boolean onPrepareOptionsMenu (Menu menu) {
        super.onPrepareOptionsMenu( menu );
        if ( !bMenuInitialized ) {
            this.menu = menu;
            getMenuInflater().inflate( R.menu.home_mainmenu, menu );
            bMenuInitialized = true;
        }
        /*
        invalidateOptionsMenu();
        toolbar.inflateMenu( R.menu.home_mainmenu );
         */
        return true;
    }

我在评论区留下了不该做什么。调用 invalidateOptionsMenu(),你会在互联网上看到它,会导致一个无限循环。不要那样做.....如果您以某种方式更改了菜单,则只能从其他代码块调用 invalidateOptionsMenu。这就是工具栏没有显示自身的原因。(通过“更改菜单”,我并不是指在 MenuItems 上设置属性。)

我还了解到,您必须创建一个标志来指示菜单是否已经膨胀,因为每次用户访问工具栏时都会调用 onPrepareOptionsMenu()。您不希望每次都不断膨胀您的菜单,因为它只是添加到已经在其中的菜单中,使其越来越长。

你有它。我希望这可以帮助别人。并感谢所有回复的人。


推荐阅读