简体   繁体   English

如何在 Android 中动态更改菜单项文本

[英]How to change menu item text dynamically in Android

I'm trying to change the title of a menu item from outside of the onOptionsItemSelected(MenuItem item) method.我正在尝试从onOptionsItemSelected(MenuItem item)方法之外更改菜单项的标题。

I already do the following;我已经做了以下事情;

public boolean onOptionsItemSelected(MenuItem item) {
  try {
    switch(item.getItemId()) {
      case R.id.bedSwitch:
        if(item.getTitle().equals("Set to 'In bed'")) {
          item.setTitle("Set to 'Out of bed'");
          inBed = false;
        } else {
          item.setTitle("Set to 'In bed'");
          inBed = true;
        }
        break;
    }
  } catch(Exception e) {
    Log.i("Sleep Recorder", e.toString());
  }
  return true;
}

however I'd like to be able to modify the title of a particular menu item outside of this method.但是我希望能够在此方法之外修改特定菜单项的标题。

I would suggest keeping a reference within the activity to the Menu object you receive in onCreateOptionsMenu and then using that to retrieve the MenuItem that requires the change as and when you need it.我建议在活动中保留对您在onCreateOptionsMenu中收到的菜单 object 的引用,然后在需要时使用它来检索需要更改的 MenuItem。 For example, you could do something along the lines of the following:例如,您可以执行以下操作:

public class YourActivity extends Activity {

  private Menu menu;
  private String inBedMenuTitle = "Set to 'In bed'";
  private String outOfBedMenuTitle = "Set to 'Out of bed'";
  private boolean inBed = false;

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Create your menu...

    this.menu = menu;
    return true;
  }

  private void updateMenuTitles() {
    MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
    if (inBed) {
      bedMenuItem.setTitle(outOfBedMenuTitle);
    } else {
      bedMenuItem.setTitle(inBedMenuTitle);
    }
  }

}

Alternatively, you can override onPrepareOptionsMenu to update the menu items each time the menu is displayed.或者,您可以覆盖onPrepareOptionsMenu以在每次显示菜单时更新菜单项。

As JxDarkAngel suggested, calling this from anywhere in your Activity ,正如 JxDarkAngel 建议的那样,从Activity的任何地方调用它,

invalidateOptionsMenu();

and then overriding:然后覆盖:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  MenuItem item = menu.findItem(R.id.bedSwitch);
    if (item.getTitle().equals("Set to 'In bed'")) {
        item.setTitle("Set to 'Out of bed'");
        inBed = false;
    } else {
        item.setTitle("Set to 'In bed'");
        inBed = true;
    }
  return super.onPrepareOptionsMenu(menu);
}

is a much better choice.是一个更好的选择。 I used the answer from https://stackoverflow.com/a/17496503/568197我使用了https://stackoverflow.com/a/17496503/568197的答案

you can do this create a global "Menu" object then assign it in onCreateOptionMenu你可以这样做创建一个全局“菜单” object 然后在 onCreateOptionMenu 中分配它

public class ExampleActivity extends AppCompatActivity
    Menu menu;

then assign here然后在这里分配

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

Then later use assigned Menu object to get required items然后稍后使用分配的菜单 object 获取所需项目

menu.findItem(R.id.bedSwitch).setTitle("Your Text");

Create a setOptionsTitle() method and set a field in your class.创建一个 setOptionsTitle() 方法并在 class 中设置一个字段。 Such as:如:

String bedStatus = "Set to 'Out of Bed'";

... ...

public void setOptionsTitle(String status)
{
    bedStatus = status;

}

Now when the menu gets populated, change the title to whatever your status is:现在,当菜单被填充时,将标题更改为您的状态:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }

You better use the override onPrepareOptionsMenu你最好使用覆盖 onPrepareOptionsMenu

menu.Clear ();
   if (TabActual == TabSelec.Anuncio)
   {
       menu.Add(10, 11, 0, "Crear anuncio");
       menu.Add(10, 12, 1, "Modificar anuncio");
       menu.Add(10, 13, 2, "Eliminar anuncio");
       menu.Add(10, 14, 3, "Actualizar");
   }
   if (TabActual == TabSelec.Fotos)
   {
       menu.Add(20, 21, 0, "Subir foto");
       menu.Add(20, 22, 1, "Actualizar");
   }
   if (TabActual == TabSelec.Comentarios)
   {
       menu.Add(30, 31, 0, "Actualizar");
   }

Here an example这里有一个例子

I use this code to costum my bottom navigation item我使用此代码来装饰我的底部导航项

BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");

Declare your menu field.声明您的菜单字段。

private Menu menu;

Following is onCreateOptionsMenu() method以下是 onCreateOptionsMenu() 方法

public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
    try {
        getMenuInflater().inflate(R.menu.menu_main,menu);
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
    }
    return super.onCreateOptionsMenu(menu);
}

Following will be your name setter activity.以下将是您的名称设置器活动。 Either through a button click or through conditional code通过单击按钮或通过条件代码

public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}

This worked for me.这对我有用。

You can do it like this, and no need to dedicate variable:你可以这样做,不需要专门的变量:

Toolbar toolbar = findViewById(R.id.toolbar);
Menu menu = toolbar.getMenu();
MenuItem menuItem = menu.findItem(R.id.some_action);
menuItem.setTitle("New title");

Or a little simplified:或者稍微简化一下:

MenuItem menuItem = ((Toolbar)findViewById(R.id.toolbar)).getMenu().findItem(R.id.some_action);
menuItem.setTitle("New title");

It works only - after the menu created.它仅在创建菜单后才有效。

It seems to me that you want to change the contents of menu inside a local method, and this method is called at any time, whenever an event is occurred, or in the activity UI thread.在我看来,您想在本地方法中更改菜单的内容,并且无论何时发生事件或在活动 UI 线程中都会调用此方法。

Why don't you take the instance of Menu in the global variable in onPrepareOptionsMenu when this is overridden and use in this method of yours.当它被覆盖并在你的这个方法中使用时,你为什么不在 onPrepareOptionsMenu 的全局变量中获取 Menu 的实例。 Be sure that this method is called whenever an event is occurred (like button click), or in the activity UI thread, handler or async-task post-execute.确保无论何时发生事件(如按钮单击),或在活动 UI 线程、处理程序或异步任务执行后调用此方法。

You should know in advance the index of this menu item you want to change.您应该事先知道要更改的此菜单项的索引。 After clearing the menu, you need to inflate the menu XML and update your item's name or icon.清除菜单后,您需要为菜单 XML 充气并更新您的项目名称或图标。

For people that need the title set statically.对于需要静态设置标题的人。 This can be done in the AndroidManifest.xml这可以在 AndroidManifest.xml 中完成

<activity
    android:name=".ActivityName"
    android:label="Title Text" >
</activity>

选项菜单标题文本

I needed to change the menu icon for the fragment.我需要更改片段的菜单图标。 I altered Charles's answer to this question a bit for the fragment:对于片段,我稍微改变了查尔斯对这个问题的回答:

    private Menu top_menu;

    //...
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       setHasOptionsMenu(true);
       //...
       rootview = inflater.inflate(R.layout.first_content,null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_menu, menu);
        this.top_menu = menu;
    }


    // my procedure
    private void updateIconMenu() {
         if(top_menu!= null) {
             MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
             nav_undo.setIcon( R.drawable.back);
         }
    }

I hit this problem too.我也遇到了这个问题。 In my case I wanted to set the string to reflect additional information using getString.就我而言,我想设置字符串以使用 getString 反映附加信息。

As stated above you need to find the correct menuItem in the menu and set it in the onPrepareOptionsMenu method.如上所述,您需要在菜单中找到正确的 menuItem 并在 onPrepareOptionsMenu 方法中进行设置。 The solutions above didn't handle the case where the item was in a sub menu and for this you need to search the submenu for the item.上面的解决方案没有处理该项目位于子菜单中的情况,为此您需要在子菜单中搜索该项目。 I wrote a little Kotlin recursive function to allow me to this for multiple items.我写了一点 Kotlin 递归 function 来允许我处理多个项目。 Code below...下面的代码...

override fun onPrepareOptionsMenu(menu: Menu) {
...
    menu.menuSetText(R.id.add_new_card,
        getString(R.string.add_card, currentDeck.deckName))
...
}
private fun Menu.getMenuItem(idx: Int, itemId: Int): MenuItem? {
    Log.d(TAG, "getMenuItem: $idx of ${this.size()}")
    if (idx >= size()) return null
    val item = getItem(idx)
    if (item.hasSubMenu()) {
        val mi = item.subMenu.getMenuItem(0, itemId)
        // mi non-null means we found item.
        if (mi != null)
            return mi
    }
    if (item != null && item.itemId == itemId)
        return item
    return getMenuItem(idx + 1, itemId)
}
fun Menu.menuSetText(itemId: Int, title: String) {
    val menuItem = getMenuItem(0, itemId)
    if (menuItem != null)
        menuItem.title = title
    else
        Log.e(TAG,
            "menuSetText to \"$title\": Failed to find ${
                "itemId:0x%08x".format(itemId)}"
        )
}

You can Change Menu Item text using below Code: -您可以使用以下代码更改菜单项文本:-

 fun showPopup(v: View) {
        popup = PopupMenu(context, v)
        val inflater = popup?.menuInflater
        popup?.setOnMenuItemClickListener(this)
        inflater?.inflate(R.menu.menu_main, popup?.menu)
        val menu: Menu = popup!!.menu
        val item = menu.findItem(R.id.name)
        if (item.title.equals("Name")) {
            item.title = "Safal Bhatia"
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM