`setSupportActionBar` 移除了菜单项。

huangapple go评论76阅读模式
英文:

setSupportActionBar removes menu items

问题

抱歉,如果我没有清楚地解释我遇到的问题。

我有一个项目使用了MaterialToolbar,它引用了一个menu.xml来定义外观。这个菜单包含了我想要使用的潜在图标(收藏,删除等)。

然而,在我的代码中,当初始化setSupportActionBar()时,它会覆盖我设置的引用,除了导航图标外,图标不再显示。

我需要setSupportActionBar()来完成项目,有没有办法在保留setSupportActionBar()的同时保持top_app_bar.xml的外观?或者至少保留菜单项中初始化的图标?

activity_main_menu.xml

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/topAppBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:menu="@menu/top_app_bar"
        app:navigationIcon="@drawable/ic_menu_24dp"
        style="@style/Widget.MaterialComponents.Toolbar.Primary"/>
</com.google.android.material.appbar.AppBarLayout>

top_app_bar.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_delete_24dp"
        android:title="test"
        app:showAsAction="ifRoom"/>
</menu>

MainMenu.java

MaterialToolbar topAppBar = findViewById(R.id.topAppBar);
setSupportActionBar(topAppBar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
英文:

Apologies if I am not explaining the issue I am having clearly enough.

I have a project that utilizes a MaterialToolbar, it references a menu.xml for its appearances. The menu holds potential icons I wish to use (favourite, delete etc).

In my code, however when initializing setSupportActionBar(), it overrides the reference I have set, the icons no longer appear aside from the Navigation icon.

I require setSupportActionBar() for my project, is there a way I can retain setSupportActionBar() while keeping the appearance of top_app_bar.xml? Or at the very least the icon initialized in the menu item?

activity_main_menu.xml

&lt;com.google.android.material.appbar.AppBarLayout
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;&gt;
    &lt;com.google.android.material.appbar.MaterialToolbar
        android:id=&quot;@+id/topAppBar&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;?attr/actionBarSize&quot;
        app:menu=&quot;@menu/top_app_bar&quot;
        app:navigationIcon=&quot;@drawable/ic_menu_24dp&quot;
        style=&quot;@style/Widget.MaterialComponents.Toolbar.Primary&quot;/&gt;
&lt;/com.google.android.material.appbar.AppBarLayout&gt;

top_app_bar.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;
    &lt;item
        android:id=&quot;@+id/delete&quot;
        android:icon=&quot;@drawable/ic_delete_24dp&quot;
        android:title=&quot;test&quot;
        app:showAsAction=&quot;ifRoom&quot;
        /&gt;
&lt;/menu&gt;

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;
    &lt;item
        android:id=&quot;@+id/delete&quot;
        android:icon=&quot;@drawable/ic_delete_24dp&quot;
        android:title=&quot;test&quot;
        app:showAsAction=&quot;ifRoom&quot;
        /&gt;
&lt;/menu&gt;

MainMenu.java

MaterialToolbar topAppBar = findViewById(R.id.topAppBar);
setSupportActionBar(topAppBar);
getSupportActionBar().setDisplayShowTitleEnabled(false);

答案1

得分: 2

这是预期的行为。当您将操作栏设置给一个 Activity 时,Activity 的作用就是决定将显示哪个菜单。

以下是来自 appcompat-1.0.0 依赖的 setSupportActionBar 方法的文档和方法声明。您可以全部阅读,但我特意从 Java 文档中选取了一个句子,并在此代码片段下方进行了提及。

/**
 * 将 {@link Toolbar} 设置为此委托的 {@link ActionBar}。
 *
 * &lt;p&gt;当设置为非空值时,{@link #getSupportActionBar()} 方法将返回
 * 一个 {@link ActionBar} 对象,可以用来控制给定的工具栏,就像它是
 * 传统的窗口装饰操作栏一样。工具栏的菜单将与 Activity 的选项菜单一起填充,
 * 并且导航按钮将通过标准的 {@link android.R.id#home home} 菜单选择操作进行连接。&lt;/p&gt;
 *
 * &lt;p&gt;为了在 Activity 的窗口内容中使用 Toolbar,
 * 应用程序不能请求窗口特性
 * {@link AppCompatDelegate#FEATURE_SUPPORT_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}。&lt;/p&gt;
 *
 * @param toolbar 要设置为 Activity 操作栏的工具栏,或者为 {@code null} 以清除它
 */
public abstract void setSupportActionBar(@Nullable Toolbar toolbar);

重点在于这句话:

 * ... 工具栏的菜单将与
 * Activity 的选项菜单一起填充并且导航按钮将通过标准的
 * {@link android.R.id#home home} 菜单选择操作进行连接 ...

这意味着您必须重写 onCreateOptionsMenu 方法,以便在活动中为操作栏创建菜单:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.resource_id, menu);
    return true;
}

默认情况下,如果您不重写此方法,菜单将被填充
> ... 与标准系统菜单项。

引用的来源(请注意,我从 onCreateOptionsMenu 的 Java 文档中删除了与此问题无关的解释):

/**
 * 初始化 Activity 的标准选项菜单的内容。您应该将菜单项放入 <var>menu</var> 中。
 *
 * &lt;p&gt;这仅在首次显示选项菜单时调用一次。
 *
 * &lt;p&gt;默认实现使用标准系统菜单项填充菜单。
 *
 * @param menu 您放置项目的选项菜单。
 *
 * @return 必须返回 true 才能显示菜单;
 *         如果返回 false,则不会显示菜单。
 */
public boolean onCreateOptionsMenu(Menu menu) {
    if (mParent != null) {
        return mParent.onCreateOptionsMenu(menu);
    }
    return true;
}
英文:

It is expected behaviour. When you set an action bar to an Activity it is the role of Activity to decide what menu will be displayed.

Here is the documentation and method declaration of setSupportActionBar from appcompat-1.0.0 dependency. You can read it all but I explicitly selected a single sentence from the java-doc and mentioned it below this snippet.

/**
 * Set a {@link Toolbar} to act as the {@link ActionBar} for this delegate.
 *
 * &lt;p&gt;When set to a non-null value the {@link #getSupportActionBar()} ()} method will return
 * an {@link ActionBar} object that can be used to control the given toolbar as if it were
 * a traditional window decor action bar. The toolbar&#39;s menu will be populated with the
 * Activity&#39;s options menu and the navigation button will be wired through the standard
 * {@link android.R.id#home home} menu select action.&lt;/p&gt;
 *
 * &lt;p&gt;In order to use a Toolbar within the Activity&#39;s window content the application
 * must not request the window feature
 * {@link AppCompatDelegate#FEATURE_SUPPORT_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}.&lt;/p&gt;
 *
 * @param toolbar Toolbar to set as the Activity&#39;s action bar, or {@code null} to clear it
 */
public abstract void setSupportActionBar(@Nullable Toolbar toolbar);

The emphasis is on this sentence:

 * ... The toolbar&#39;s menu will be populated with the
 * Activity&#39;s options menu and the navigation button will be wired through the standard
 * {@link android.R.id#home home} menu select action ...

It means you have to override onCreateOptionsMenu method in order to create menu in the activity for the action bar:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.resource_id, menu);
    return true;
}

By default, if you do not override this method, the menu will be populated
> ... with standard system menu items.

Source of the quote (note, I removed explanations from java-doc of onCreateOptionsMenu that are irrelevant to this issue):

/**
 * Initialize the contents of the Activity&#39;s standard options menu.  You
 * should place your menu items in to &lt;var&gt;menu&lt;/var&gt;.
 *
 * &lt;p&gt;This is only called once, the first time the options menu is
 * displayed.
 *
 * &lt;p&gt;The default implementation populates the menu with standard system
 * menu items. 
 *
 * @param menu The options menu in which you place your items.
 *
 * @return You must return true for the menu to be displayed;
 *         if you return false it will not be shown.
 */
public boolean onCreateOptionsMenu(Menu menu) {
    if (mParent != null) {
        return mParent.onCreateOptionsMenu(menu);
    }
    return true;
}

huangapple
  • 本文由 发表于 2020年9月6日 15:32:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63761776.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定