根据导航目的地更新 ActionBar 菜单

Posted

技术标签:

【中文标题】根据导航目的地更新 ActionBar 菜单【英文标题】:Update ActionBar menu depending on navigation destination 【发布时间】:2019-09-10 23:49:46 【问题描述】:

我想根据我的NavController 的当前目的地更改我的ActionBar 中显示的菜单项。通过“更改”,我的意思是为每个目的地膨胀指定的 menu-xml。

该行为可以与新导航系统更改 ActionBar 标题的集成方式进行比较,具体取决于导航 xml 中目标片段的给定 android:label

到目前为止,我使用新的 Android 导航设置了 ActionBarDrawerLayout 的基本活动。我还创建了所有必要的 XML 文件和片段以在它们之间导航。

...

@Override
protected void onCreate(Bundle savedInstanceState)

    ...    

    this._drawerLayout = this.findViewById(R.id.drawer_layout);

    Toolbar toolbar = this.findViewById(R.id.action_bar);
    this.setSupportActionBar(toolbar);

    ActionBar actionbar = Objects.requireNonNull( this.getSupportActionBar() );
    actionbar.setDisplayHomeAsUpEnabled(true);
    actionbar.setHomeAsUpIndicator(R.drawable.ic_menu);

    NavigationView navigationView = this.findViewById(R.id.navigation_view);
    navigationView.setNavigationItemSelectedListener(menuItem -> 
        menuItem.setChecked(true);
        this._drawerLayout.closeDrawers();

        return true;
    );

    NavController navController = Navigation.findNavController(this, R.id.navigation_host);
    NavigationUI.setupWithNavController(toolbar, navController, this._drawerLayout);


@Override
public boolean onCreateOptionsMenu(Menu menu)

    // Here I inflate the ActionBar menu that is kept between all destinations.
    // Instead of keeping the same menu between all destinations I want to display different menus depending on the destination fragment.
    this.getMenuInflater().inflate(R.menu.actionbar_items, menu);

    return true;


@Override
public boolean onOptionsItemSelected(MenuItem item)

    switch(item.getItemId())
    
        case android.R.id.home:
            this._drawerLayout.openDrawer(GravityCompat.START);
            return true;
        case R.id.appbar_search:
            return true;
    

    return super.onOptionsItemSelected(item);


我考虑在每个目标片段中使用单独的工具栏 但我放弃了这个想法,因为我会失去汉堡图标和后退箭头图标之间的过渡动​​画。

有没有什么方法可以通过新的导航系统或其他方式来实现这一点?

【问题讨论】:

【参考方案1】:

我刚刚测试了这个。在导航库的当前版本 (2.2.2) 中,由每个片段膨胀的菜单项将在您导航时添加和删除。

但默认不调用 onCreateOptionsMenu!为了使事情顺利进行,您必须在初始化期间撒上魔法灰尘并调用setHasOptionsMenu(true)

请注意,由包含的 Activity 膨胀的任何菜单项将始终与当前片段中的菜单项一起出现,因此如果您不想要任何常见的菜单项,最简单的方法可能是不在 Activity 中膨胀菜单。

附注:在Fragment 类中,onCreateOptionsMenu(menu, inflater) 是一个空方法,因此在您的代码中调用super.onCreateOptionsMenu(menu, inflater) 是无操作的。

【讨论】:

【参考方案2】:

我找到了一种方法来实现所需的行为,方法是在扩展更新的布局之前调用menu.clear();。我仍然想知道新导航系统是否有内置的方法来实现这一点。

在我现在使用的目标片段中:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)

    super.onCreateOptionsMenu(menu, inflater);

    menu.clear();
    inflater.inflate(R.menu.toolbar_items_idle, menu);

【讨论】:

以上是关于根据导航目的地更新 ActionBar 菜单的主要内容,如果未能解决你的问题,请参考以下文章

android-ActionBar

手动打开 ActionBar 导航列表

设置 ActionBar 上所选项目的标题

个人知识体系(持续更新)

个人知识体系(持续更新)

Android中活动条ActionBar的详细使用