android - 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。
解决方案
好吧,我最终确实弄明白了。重复一下,我正在使用这个库:
导入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()。您不希望每次都不断膨胀您的菜单,因为它只是添加到已经在其中的菜单中,使其越来越长。
你有它。我希望这可以帮助别人。并感谢所有回复的人。
推荐阅读
- python - 使用 BeautifulSoup提取包含 `
` 的字符串返回 `None` - r - 在 R 中重复复制()以逐步向前/向后更改(每次更改种子)
- regex - URL 仅重写主请求并忽略子文件夹
- python - 如何使饼图的一部分透明
- javascript - 如何跳过值实时数据库firebase
- python - 如何使用基于主题的 Python 在 Outlook 中创建规则
- python - 如何获取两个日期时间之间的每周日期时间范围并在 Python 中返回数据框
- python - Discord Bot 无法播放 YouTube 视频
- reactjs - JWT 和 react,react 从 token 中获取信息
- sql - 输出中没有时间戳的 date_trunc 函数