隐藏/显示不同片段的操作栏选项菜单项

Posted

技术标签:

【中文标题】隐藏/显示不同片段的操作栏选项菜单项【英文标题】:Hide/Show Action Bar Option Menu Item for different fragments 【发布时间】:2014-06-04 09:53:09 【问题描述】:

我有一个夏洛克片段活动,其中有 3 个片段。

Fragment A、Fragment B、Fragment C 是三个片段。我只想在片段 B 中显示完成选项菜单。

和活动以片段A启动。选择片段B完成后,添加按钮。

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


@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    if(!menusInflated)
        inflater.inflate(R.menu.security, menu);
        menusInflated=true;
    

    super.onCreateOptionsMenu(menu, inflater);

当我再次启动 Fragment A 时,我想为此选择 Menu DONE(在 Fragment B 中设置),我正在这样做

setHasOptionsMenu(false);
MenuItem item = (MenuItem) menu.findItem(R.id.done_item);
item.setVisible(false);

但这根本没有隐藏,如果第一次从 Fragment A 启动,它也会在 Activity 时给出 NullPointerException。

请告诉我是什么问题。

【问题讨论】:

你的问题解决了吗? , 我也有同样的问题。谢谢 此问题与您遇到的问题不一致。您不需要从操作栏中“隐藏”按钮,您需要确保操作栏选项为不同的片段正确加载。在每个 onCreateOptionsMenu() 函数中膨胀菜单之前使用 menu.clear() ,这将删除其中所有过时的选项。 只是为了澄清一下,在您的情况下,您需要在片段 A 中使用空/默认菜单覆盖 onCreateOptionsMenu()(并使用 menu.clear())。您可能还需要为 Fragment C 执行此操作。手动确保 ActionBar 菜单在 Fragment 中的行为正确是使用 Fragments 来显示内容而不是使用活动的成本。 如果以下任何答案对您有所帮助,请接受答案作为解决方案。 【参考方案1】:

试试这个...

您不需要再次覆盖 Fragment 类中的 onCreateOptionsMenu()。可以通过覆盖 Fragment 类中可用的 onPrepareOptionsMenu() 方法来更改菜单项的可见性。

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

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

【讨论】:

最适合我!这应该是公认的答案。 我试图将此表单称为从 AppCompatActivity 派生的活动,而 setHasOptionsMenu() 方法无法解析。 @techtinkerer:您应该在 Fragmant 中覆盖这些方法,这些方法会覆盖父 Activity 中的 onCreateOptionsMenu()。 我必须在所有我想隐藏图标的片段上添加setHasOptionsMenu(true) in onViewCreated。有什么办法我可以只写一次setHasOptionsMenu 并且图标隐藏在我覆盖onPrepareOptionsMenu 的任何片段上? @Chinmay Sarupria,是的,你可以!创建一个 BaseFragment 并在该片段中执行此操作,然后将其扩展到您要隐藏的子片段。【参考方案2】:

这是这样做的一种方法:

在您的菜单中添加一个“组”:

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

    <group
        android:id="@+id/main_menu_group">
         <item android:id="@+id/done_item"
              android:title="..."
              android:icon="..."
              android:showAsAction="..."/>
    </group>
</menu>

然后,添加一个

Menu menu;

为您的活动设置变量并将其设置在您的 onCreateOptionsMenu 覆盖中:

@Override
public boolean onCreateOptionsMenu(Menu menu) 
    this.menu = menu;
    // inflate your menu here

之后,当您想显示/隐藏菜单时,添加并使用此功能到您的活动中:

public void showOverflowMenu(boolean showMenu)
    if(menu == null)
        return;
    menu.setGroupVisible(R.id.main_menu_group, showMenu);

我并不是说这是最好/唯一的方法,但它对我很有效。

【讨论】:

我认为这是一个很好的解决方案!它简单干净。 我没有尝试过,但是 Silambarasan 提供的以下代码对我来说非常有用。 最佳解决方案!谢谢! 对我来说不适用于搜索项和 app:actionViewClass="android.support.v7.widget.SearchView" 。当我关闭搜索视图时,发生了一些有趣的事情。【参考方案3】:

要在片段的 ActionBar 中仅需要它们的地方显示操作项(操作按钮),请执行以下操作:

假设您希望 save 按钮仅显示在您接受项目输入的片段中,而不显示在您查看项目列表的片段中,请将其添加到片段的 OnCreateOptionsMenu 方法中查看项目:

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 

    if (menu != null) 

        menu.findItem(R.id.action_save_item).setVisible(false);
    

注意:为此,您需要在 Fragment 中使用 onCreate() 方法(您要在其中隐藏项目按钮,在我们的示例中为项目视图片段)并添加 setHasOptionsMenu(true) like这个:

public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);

可能不是最好的选择,但它很有效而且很简单。

【讨论】:

比公认答案更干净的解决方案【参考方案4】:

我猜这肯定会起作用...

// Declare
Menu menu;
MenuItem menuDoneItem;

// Then in your onCreateOptionMenu() method write the following...
@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
        this.menu=menu;
        inflater.inflate(R.menu.secutity, menu);
            

// In your onOptionItemSelected() method write the following...
@Override
    public boolean onOptionsItemSelected(MenuItem item) 
        switch (item.getItemId()) 
            case R.id.done_item:
                this.menuDoneItem=item;
                someOperation();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        
    

// Now Making invisible any menu item...
public void menuInvisible()
setHasOptionsMenu(true);// Take part in populating the action bar menu
            menuDoneItem=(MenuItem)menu.findItem(R.id.done_item);
                menuRefresh.setVisible(false); // make true to make the menu item visible.


//Use the above method whenever you need to make your menu item visible or invisiable

您也可以参考这个link了解更多详情,它非常有用。

【讨论】:

【参考方案5】:
MenuItem Import = menu.findItem(R.id.Import);
  Import.setVisible(false)

【讨论】:

【参考方案6】:

试试这个

@Override
public boolean onCreateOptionsMenu(Menu menu)
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.custom_actionbar, menu);
    menu.setGroupVisible(...);

【讨论】:

请添加一些 cmets 解释您如何回答问题 - 不鼓励仅使用代码回答。【参考方案7】:

通过设置Menu中所有项目的Visibility,appbar菜单或溢出菜单会自动隐藏

例子

 private Menu menu_change_language;
 ...
 ...
 @Override
 public boolean onCreateOptionsMenu(Menu menu) 
    ...
    ...
    menu_change_language = menu;
   menu_change_language.findItem(R.id.menu_change_language).setVisible(true);

    return super.onCreateOptionsMenu(menu);

在去其他片段之前使用下面的代码:

if(menu_change_language != null)                 
 menu_change_language.findItem(R.id.menu_change_language)
  .setVisible(false);

【讨论】:

【参考方案8】:

您可以为每个片段创建一个菜单,以及一个标记当前正在使用的片段的全局变量。 并检查 onCreateOptionsMenu 中变量的值并膨胀正确的菜单

 @Override
     public boolean onCreateOptionsMenu(Menu menu) 
         if (fragment_it == 6) 
             MenuInflater inflater = getMenuInflater();
             inflater.inflate(R.menu.custom_actionbar, menu);
         
      

【讨论】:

但是片段中onOptionSelected的代码怎么写呢? 你应该把它写在Activity的类而不是fragment的fragment_it会指出你现在正在使用哪个fragment然后你膨胀相应的菜单【参考方案9】:

您好,我得到了最好的解决方案,假设您必须在 create Menu 方法中隐藏特定项目并在其他片段中显示该项目。我以两个菜单项为例,一个是编辑,另一个是删除。例如,菜单 xml 如下所示:

sell_menu.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/action_edit"
    android:icon="@drawable/ic_edit_white_shadow_24dp"
    app:showAsAction="always"
    android:title="Edit" />

<item
    android:id="@+id/action_delete"
    android:icon="@drawable/ic_delete_white_shadow_24dp"
    app:showAsAction="always"
    android:title="Delete" />

现在在您的活动中覆盖这两个方法并将字段变量 mMenu 设为:

  private Menu mMenu;         //  field variable    


  @Override
  public boolean onCreateOptionsMenu(Menu menu) 
    getMenuInflater().inflate(R.menu.sell_menu, menu);
    this.mMenu = menu;

    menu.findItem(R.id.action_delete).setVisible(false);
    return super.onCreateOptionsMenu(menu);
  

 @Override
 public boolean onOptionsItemSelected(MenuItem item) 
    if (item.getItemId() == R.id.action_delete) 
       // do action
        return true;
     else if (item.getItemId() == R.id.action_edit) 
      // do action
        return true;
    

    return super.onOptionsItemSelected(item);
 

在您的活动中创建两个以下方法并从片段中调用它们以隐藏和显示您的菜单项。这些方法如下:

public void showDeleteImageOption(boolean status) 
    if (menu != null) 
        menu.findItem(R.id.action_delete).setVisible(status);
    


public void showEditImageOption(boolean status) 
    if (menu != null) 
        menu.findItem(R.id.action_edit).setVisible(status);
    

这是我这边的解决方案,我认为这个解释会对你有所帮助。

【讨论】:

【参考方案10】:

即使这个问题已经过时并且已经得到解答。有一个比上面提到的更简单的答案。您不需要使用任何其他变量。 您可以在操作栏上创建任何您想要的片段的按钮,而不是做可见性的东西(显示/隐藏)。

在片段中添加您需要的菜单项。

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    inflater.inflate(R.menu.menu, menu);
    super.onCreateOptionsMenu(menu, inflater);

示例 menu.xml 文件:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/action_addFlat"
        android:icon="@drawable/add"
        android:showAsAction="ifRoom|withText"
        android:title="@string/action_addFlat"/>
</menu>

像往常一样处理 onclick 事件。

【讨论】:

这正是我所做的,但对我不起作用。切换到另一个片段时(我使用的是 ViewPager),添加的项目仍然可见。【参考方案11】:

聚会迟到了,但上面的答案似乎对我不起作用。

我的第一个选项卡片段(内部选项卡使用 getChildFragmentManager())具有显示搜索图标的菜单并使用 android.support.v7.widget.SearchView 在内部选项卡片段中搜索,但导航到其他选项卡(也使用 getChildFragmentManager()) 的内部选项卡不会删除搜索图标(不是必需的),因此仍然可以在没有任何功能的情况下访问,可能是因为我正在使用下面的(即带有每个内部选项卡的外部主选项卡)

getChildFragmentManager(); 

但是,我在包含/使用 getChildFragmentManager() 的片段中使用以下内容作为内部选项卡。

    //region onCreate
    @Override
    public void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState);
    setRetainInstance(true);

    //access setHasOptionsMenu()
    setHasOptionsMenu(true);

    
    //endregion onCreate

然后清除 onPrepareOptionsMenu 中的菜单项以获取片段(搜索图标和功能)

    @Override
    public void onPrepareOptionsMenu(Menu menu) 

    super.onPrepareOptionsMenu(menu);

    //clear the menu/hide the icon & disable the search access/function ...
    //this will clear the menu entirely, so rewrite/draw the menu items after if needed
    menu.clear();

    

效果很好,导航回带有搜索图标功能的选项卡/内部选项卡重新显示搜索图标和功能。

希望这会有所帮助...

【讨论】:

【参考方案12】:

好的,我花了几个小时来获得这个解决方案。显然,您可以从工具栏中获取 menuitem 到活动或片段中的任何位置。所以就我而言。

var menuItem = toolbar.menu;   

现在从菜单项中获取特定项

favIcon = menuItem.findItem(R.id.favourite);      

注意:favIcon 是 MenuItem 声明全局 现在,如果你可以为这个图标做任何你想做的事情 例如。让它不可见

favIcon?.isVisible=false

【讨论】:

【参考方案13】:

由于某种原因,该方法对我不起作用,这就是我根据接受的解决方案解决它的方法

//This should be in on create
new Handler().postDelayed(new Runnable() 
            @Override
            public void run() 
                showOverflowMenu(false);
            
        ,100);


@Override
    public boolean onCreateOptionsMenu(Menu menu) 
        this.menu = menu;
        getMenuInflater().inflate(R.menu.options_menu, menu);
        return true;
    



public void showOverflowMenu(boolean showMenu)
        if(menu == null)
            return;
        menu.setGroupVisible(R.id.grp, showMenu);
    

【讨论】:

以上是关于隐藏/显示不同片段的操作栏选项菜单项的主要内容,如果未能解决你的问题,请参考以下文章

如何通过单击选项卡来更改操作栏菜单按钮

Android选择条目时下方出现菜单选项

WPF中我在最上面添加一个菜单栏,点击不同的菜单选项,然后在下面的区域显示不同的界面,请问怎样实现?

每个选项下拉项显示不同的内容

winform菜单栏工具栏

FragmentActivity 操作栏选项菜单