android:以编程方式更改选项菜单项


89

是否可以通过编程方式更改选项菜单项?有人可以给我提供一个例子吗?

另外,我想禁用某些项目,以使它们不听点击声,可以吗?

Answers:


211

对于任何需要动态更改菜单选项的人:

private Menu menu;

// ...

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

// ...

private void hideOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(false);
}

private void showOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(true);
}

private void setOptionTitle(int id, String title)
{
    MenuItem item = menu.findItem(id);
    item.setTitle(title);
}

private void setOptionIcon(int id, int iconRes)
{
    MenuItem item = menu.findItem(id);
    item.setIcon(iconRes);
}

8
一个警告是,您必须先确定menu已设置好它,然后才能尝试使用MenuItem它。例如,如果您有类似的内容actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS),那么选项卡将在菜单之前加载,因此在内部调用hideOption/会导致空指针异常。showOptiononTabSelected
SaltyNuts

当我使用时item.setVisible(false);,仅当我单击菜单本身时,该项目才会被隐藏。如果我使用invalidateOptionsMenu();该物品,请不要点击。如果您能在我面临的类似问题上帮助我,我将不胜感激。stackoverflow.com/questions/54756799/…–
阿里顿·奥利维拉

@AlitonOliveira,应通过检查标志变量状态将您的item.setVisibility(false)部分放在onCreateOptionsMenu方法中,并且应更改标志和invalidateOptionsMenu的布尔值。它会工作。
Kidus Tekeste

setVisible状态文档,您也应该调用setEnabled(false)该项目,否则仍可以通过其快捷方式调用该项目
Florian Walther

34

menu.xml

  <item 
    android:id="@+id/item1"
    android:title="your Item">
  </item>

放在你的java文件中

  public void onPrepareOptionsMenu(Menu menu) {

    menu.removeItem(R.id.item1);
}

这是我一直在寻找的,因为我想在运行时一次做出决定,但之后不需要更改选项。我使用过:@Override public boolean onPrepareOptionsMenu(Menu menu){if(!showItemName){menu.removeItem(R.id.itemname); 返回true;}
notmystyle

20

就像尼古拉所说的那样,可以在onPrepareOptionsMenu()中做到这一点。

对于操作栏中的菜单项,您必须使用 activity.invalidateOptionsMenu();

这在此处更详细地描述


7

如果必须更改选项菜单的内容,请在onMenuOpened()期间执行它。这使我可以在用户访问菜单时检查运行状态。

public boolean onMenuOpened(int featureid, Menu menu)
    {
        menu.clear();
        if (!editable)
        {
            MenuItem itemAdd = menu.add(0, REASSIGN, Menu.NONE, context.getString(R.string.reassign));
            MenuItem itemMod = menu.add(1, EDIT, Menu.NONE, context.getString(R.string.modify));
            MenuItem itemDel = menu.add(2, DELETE, Menu.NONE, context.getString(R.string.delete));
            itemAdd.setShortcut('0', 'a');
            itemMod.setShortcut('1', 'm');
            itemDel.setShortcut('2', 'd');
        }
        else
        {
            MenuItem itemSave = menu.add(3, SAVE, Menu.NONE, context.getString(R.string.savechanges));
            itemSave.setShortcut('0', 'S');
        }


        return true;
    }

几句话。onMenuOpened被调用两次。第一次菜单var为空,第二次菜单var准备使用。我总是使用'​​if'子句检查menu var是否不为null。
肯德兹·皮斯托莱(KsiądzPistolet)

7

禁用某些项目:

MenuItem item = menu.findItem(R.id.ID_ASSING_TO_THE_ITEM_IN_MENU_XML);
item.setEnabled(false);

设置时item.setVisible(false);,仅当我单击菜单本身(三个点)时,我的项目才会隐藏。如果我使用invalidateOptionsMenu();某些物品,请不要点击。如果您能在我面临的类似问题上帮助我,我将不胜感激。stackoverflow.com/questions/54756799/…–
阿里顿·奥利维拉

4

我使用以下几行将菜单中的值添加

getActivity().invalidateOptionsMenu();

尝试这项工作对我来说就像一种魅力。


3

试试这个代码:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu=menu;
    updateMenuItems(menu);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.document_list_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    if (item.getItemId() == android.R.id.home) {
        onHomeButtonPresssed();
    }else if (item.getItemId() == R.id.action_delete) {
        useCheckBoxAdapter=false;
        deleteDocuments();
    } else if (item.getItemId() == R.id.share) {
        useCheckBoxAdapter=false;
        shareDocuments();
    } else if (item.getItemId() == R.id.action_tick) {
        useCheckBoxAdapter=true;
        onShowCheckboxes();
    }
    updateMenuItems(menu);
    return true;
}

private void updateMenuItems(Menu menu){
    if (useCheckBoxAdapter && menu != null) {
        menu.findItem(R.id.action_delete).setVisible(true);
        menu.findItem(R.id.share).setVisible(true);
        menu.findItem(R.id.action_tick).setVisible(false);
    } else {
        menu.findItem(R.id.action_delete).setVisible(false);
        menu.findItem(R.id.share).setVisible(false);
        menu.findItem(R.id.action_tick).setVisible(true);
    }
    invalidateOptionsMenu();
}

使用时invalidateOptionsMenu();,我总是可见的项目停止工作(我的意思是这些项目对点击没有响应)。如果您能在我面临的类似问题上帮助我,我将不胜感激。stackoverflow.com/questions/54756799/…–
阿里顿·奥利维拉

2

您可以像我一样做一些简单的事情。只需将文本更改为触摸菜单项时所需的内容即可。我需要打开和关闭声音,以及通过触摸来执行动作的功能。这是我的代码:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.audioOn:
        audioOn = !audioOn;
        if (audioOn)
            item.setTitle("Audio Off");
        else
            item.setTitle("Audio On");
        return true;

    case R.id.touchOn:
        touchOn = !touchOn;
        if (touchOn)
            item.setTitle("Touch Off");
        else
            item.setTitle("Touch On");
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

在代码的其他部分,对audioOn和touchOn进行了布尔检查。希望这可以帮助。


我如何动态地做到这一点。我的意思是...在选择一个选项项时调用一个Web服务,然后在其成功响应后...在调用onCreateOptionsMenu。怎么做?
Narendra Singh

1

您只需执行以下操作即可完成任务:

private Menu menu;

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

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu = menu;
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_toggle_grid) {
        handleMenuOption(id);
        return true;

    } else if(id == R.id.action_toggle_list){
        handleMenuOption(id);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void handleMenuOption(int id) {
    MenuItem item = menu.findItem(id);
    if (id == R.id.action_toggle_grid){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_list).setVisible(true);
    }else if (id == R.id.action_toggle_list){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_grid).setVisible(true);
    }
}

1

如果您有一个BottomBar:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    if (mBottomBar.getCurrentTabId() == R.id.tab_more) {
        getMenuInflater().inflate(R.menu.more_menu, menu);
    }

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.preferences:
            startActivity(new Intent(this, PreferenceActivity.class));
            break;
    }

    return super.onOptionsItemSelected(item);
}

然后,您只需致电:

@Override
public void onBottomBarClick(int tabId) {
    supportInvalidateOptionsMenu();
}

1

Kotlin代码,用于以编程方式访问工具栏OptionsMenu项并更改文本/图标,..:

1-我们将菜单项放在菜单项文件中,例如: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/balance"
      android:title="0"
      android:orderInCategory="100"
      app:showAsAction="always" />
 </menu>

2-在类中定义用于访问菜单对象的变量:

var menu: Menu? = null

3-在onCreateOptionsMenu中将其初始化:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    this.menu = menu
    return true
}

4-访问代码或乐趣中的菜单项:

private fun initialBalanceMenuItemOnToolbar() {
var menuItemBalance = menu?.findItem(R.id.balance)
    menuItemBalance?.title = Balance?.toString() ?: 0.toString()
    // for change icon : menuWalletBalance?.icon
}

1
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.calendar, menu);
        if(show_list == true) {         

        if(!locale.equalsIgnoreCase("sk")) menu.findItem(R.id.action_cyclesn).setVisible(false);

        return true;
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.