如何使用碎片隐藏导航抽屉上的选项菜单?

时间:2014-02-17 14:31:02

标签: android android-fragments navigation-drawer android-optionsmenu

我正在创建Android应用程序,我试图尽可能地尊重最新的Android可用性标准。特别是,我正在使用导航抽屉准备用户界面,我正在努力确保与2.1+ Android版本的兼容性。为了理解这个问题,该项目包括:

  • 主要活动;
  • 导航抽屉;
  • 四个片段(及其相关布局)。

打开导航抽屉时遇到的问题是:虽然每个Fragment都有其特定的菜单,但当我打开导航抽屉时,它会被添加到导航抽屉菜单中。我尝试了多种方式(invalidateOptionMenu()menu.clear(),操作函数isDrawerOpen()isDrawerClose()等等,但我在打开时无法删除Fragment的菜单导航抽屉。

这些是我的代码的一些片段,其中大部分是由Android Studio生成的,我正在使用的IDE:

在主要活动中:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (!mNavigationDrawerFragment.isDrawerOpen()) {
        // Only show items in the action bar relevant to this screen
        // if the drawer is not showing. Otherwise, let the drawer
        // decide what to show in the action bar.
        getMenuInflater().inflate(R.menu.global, menu);
        restoreActionBar();
        return true;
    }
    return super.onCreateOptionsMenu(menu);
}

其中“global”是一个带有经典“ic_action_overflow”的简单菜单。

在我的片段中我已经:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.fragment1, menu);
}

(与其他Fragment s相同。

有人可以就如何采取行动给我一些建议吗?

4 个答案:

答案 0 :(得分:12)

我使用Android Studio生成的样板代码遇到了同样的问题,并通过修改NavigationDrawerFragment.onPrepareOptionsMenu()中的菜单来实现它(在我的情况下,我想完全清除菜单):

@Override
public void onPrepareOptionsMenu(Menu menu) {
    if (mDrawerLayout != null && isDrawerOpen()) {
        menu.clear();
    }
}

这大致是重新创建选项菜单的方式:

    由IDE生成的
  1. NavigationDrawerFragment在打开或关闭抽屉时调用supportInvalidateOptionsMenu()
  2. onCreateOptionsMenu gets called:托管活动和每个添加的片段都有机会提供菜单项。
  3. onPrepareOptionsMenu gets called:同样,托管活动和每个添加的片段都有机会修改菜单。
  4. 片段是iterated in the order they were added。在步骤2和3中途无法停止呼叫链。

    因此,我们的想法是让NavigationDrawerFragment对其onPrepareOptionsMenu中的菜单进行最后一分钟的更改,而不是其他片段。

    如果您需要让其他片段在onPrepareOptionsMenu中执行某些操作,那么您可能必须设置其他片段,以便他们可以确定抽屉是否打开并相应地更改其行为。这可能意味着可能会在托管活动中添加isDrawerOpen方法,或者将抽屉标识符传递给片段,就像在NavigationDrawerFragment.setup()中完成一样。

答案 1 :(得分:5)

在你的片段onCreate中,添加:

setHasOptionsMenu (true);

然后通过onPrepareOptionsMenu隐藏。例如

@Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        menu.findItem(R.id.action_settings).setVisible(false);
    }

答案 2 :(得分:0)

在此处查看此答案:https://stackoverflow.com/a/18135409/2558344。它基本上使用布尔值来清除导航抽屉中的项目,反之亦然。但另外,您可以在类中将Menu menu声明为私有变量,并将其用作:onCreateOptionsMenu(menu, MenuInflater inflater)

然后检查您的片段onStop()onPause()是否显示项目,如果是,则清除它们,如:

if (menu != null)
    menu.clear();

答案 3 :(得分:0)

如果您已经使用NavigationDrawerFragment在Android示例代码中为您设置导航抽屉的方式,那么您应该有两个xml以main.xml开头(活动范围广泛)操作栏菜单项)和global.xml(全局项)。然后我添加了一个片段特定的菜单,它将项目添加到"活动菜单项"只要抽屉关闭......

的活动:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (!mNavigationDrawerFragment.isDrawerOpen()) {
        // Only show items in the action bar relevant to this activity
        // if the drawer is not showing. Otherwise, let the drawer
        // decide what to show in the action bar.
        getMenuInflater().inflate(R.menu.main, menu);
        this.menu = menu;
        restoreActionBar();
        return true;
    }
    return super.onCreateOptionsMenu(menu);
}

NavigationDrawerFragment

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // If the drawer is open, show the global app actions in the action bar. 
    // See also showGlobalContextActionBar, which controls the top-left area 
    // of the action bar.
    if (mDrawerLayout != null && isDrawerOpen()) {
        inflater.inflate(R.menu.global, menu);
        showGlobalContextActionBar();
    }
    super.onCreateOptionsMenu(menu, inflater);
}

并在您的片段中添加如上所述

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Add fragment specific action bar items to activity action bar items.
    // Activity wide items are in main.xml
    // Visible action bar items if navigation drawer is visible/open 
    // are in global.xml
    super.onCreateOptionsMenu(menu, inflater);
    if (!mNavigationDrawerFragment.isDrawerOpen()) {
        inflater.inflate(R.menu.fragment_menu, menu);
    }
}