【问题标题】:How to change menu item text dynamically in Android如何在 Android 中动态更改菜单项文本
【发布时间】:2011-10-27 08:32:39
【问题描述】:

我正在尝试从 onOptionsItemSelected(MenuItem item) 方法之外更改菜单项的标题。

我已经做了以下事情;

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;
}

但是我希望能够在此方法之外修改特定菜单项的标题。

【问题讨论】:

标签: java android menu menuitem


【解决方案1】:

我建议在活动中保留对您在onCreateOptionsMenu 中收到的 Menu 对象的引用,然后在您需要时使用它来检索需要更改的 MenuItem。例如,您可以执行以下操作:

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);
    }
  }

}

或者,您可以覆盖onPrepareOptionsMenu 以在每次显示菜单时更新菜单项。

【讨论】:

  • 我一直希望 Android 能够为这类问题提供更优雅的解决方案。似乎最简单的答案往往是最好的 - 谢谢。
【解决方案2】:

正如 JxDarkAngel 建议的那样,从您的 Activity 中的任何位置调用它,

invalidateOptionsMenu();

然后覆盖:

@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);
}

是一个更好的选择。我使用了https://stackoverflow.com/a/17496503/568197的答案

【讨论】:

  • 最佳解决方案。因为这个重写了android方法而不是重新发明轮子。
  • 请注意,onPrepareOptionsMenu() 被 Android 框架相当频繁地调用,例如在显示 Activity 时和每次显示菜单时。因此,如果您的菜单不经常更改,这可能不是很有效。
  • invalidateOptionsMenu() 也会调用onCreateOptionsMenu(),所以你可以把更新逻辑放在onCreateOptionsMenu()中。
  • @Garbit 更新为使用原始问题中的代码!
  • 接受 - 永恒的业力等待:)
【解决方案3】:

您可以这样做创建一个全局“菜单”对象,然后在 onCreateOptionMenu 中分配它

public class ExampleActivity extends AppCompatActivity
    Menu menu;

然后在这里赋值

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

然后使用分配的 Menu 对象来获取所需的项目

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

【讨论】:

  • 这是我首先想到的第一个解决方案,它确实有效。
【解决方案4】:

创建一个 setOptionsTitle() 方法并在您的类中设置一个字段。如:

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

...

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

}

现在,当菜单被填充时,将标题更改为您的状态:

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

        menu.add(bedStatus);


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

【讨论】:

  • 我需要能够在活动被渲染后进行设置。因此,不在这两种方法中
  • 在您的活动被渲染后的任何时候调用 setOptionsTitle。我想我不明白你想要什么,因为在你调用 setContent(R.layout.id) 之后“我需要能够在活动被渲染后设置它”对我意味着,你可能需要更改选项菜单显示(您可以使用 setOptionsTitle() 执行此操作 - 从任何方法、任何地点、任何时间)。
  • 虽然这种方法确实有效,但不推荐使用,因为管理菜单的 Menu 对象不知道标题何时更改,因此无法执行它可能需要的任务。标题更改,例如布局和换行符。
【解决方案5】:

你最好使用覆盖 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");
   }

这里an example

【讨论】:

  • 确实,使用预期的方法。 :) 如果您决定保留对菜单的本地引用,您将需要担心我认为的上下文泄漏。或者可能不是。但肯定不是这种方法。
【解决方案6】:

我使用此代码来装饰我的底部导航项

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

【讨论】:

    【解决方案7】:

    声明您的菜单字段。

    private Menu menu;
    

    以下是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);
    }
    

    以下将是您的名称设置器活动。通过按钮单击或通过条件代码

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

    这对我有用。

    【讨论】:

      【解决方案8】:

      你可以这样做,并且不需要专用变量:

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

      或者稍微简化一下:

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

      仅在创建菜单后才有效。

      【讨论】:

      • 如果您使用标准工具栏作为默认主题,它可以工作,但如果您使用自定义工具栏,则不工作
      • 是的,菜单来自:“Menu menu = toolbar.getMenu();”否则需要添加您的自定义菜单...
      【解决方案9】:

      在我看来,您想在本地方法中更改菜单的内容,并且在任何时候发生事件时或在活动 UI 线程中都会调用此方法。

      当它被覆盖并在你的这个方法中使用时,你为什么不在 onPrepareOptionsMenu 的全局变量中获取 Menu 的实例。确保无论何时发生事件(如按钮单击),或在活动 UI 线程、处理程序或异步任务执行后调用此方法。

      您应该提前知道要更改的此菜单项的索引。清除菜单后,您需要扩充菜单 XML 并更新您的项目名称或图标。

      【讨论】:

        【解决方案10】:

        对于需要静态设置标题的人。 这可以在 AndroidManifest.xml 中完成

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

        【讨论】:

        • 问题是动态的,不是静态的!
        • 仍然出现在谷歌搜索并帮助了我,感谢发帖
        【解决方案11】:

        我需要更改片段的菜单图标。我为片段修改了查尔斯对这个问题的回答:

            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);
                 }
            }
        

        【讨论】:

          猜你喜欢
          • 2017-10-25
          • 1970-01-01
          • 2011-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多