【问题标题】:android: changing option menu items programmaticallyandroid:以编程方式更改选项菜单项
【发布时间】:2011-10-31 06:43:47
【问题描述】:

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

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

【问题讨论】:

    标签: java android option menuitem


    【解决方案1】:

    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); } 返回真; }
    【解决方案2】:

    如果我必须更改选项菜单的内容,我会在 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 被调用两次。第一次 menu var 为空,第二次 menu var 准备使用。我总是使用“if”子句来检查菜单变量是否为空。
    【解决方案3】:

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

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

    【讨论】:

    • 一个警告是,在尝试从中获取MenuItem 之前,您必须确保已设置menu。例如,如果您有 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS) 之类的内容,则选项卡会在菜单之前加载,因此在 onTabSelected 内调用 hideOption/showOption 会导致空指针异常。
    • 当我使用item.setVisible(false); 时,只有当我单击菜单本身时,该项目才会隐藏。如果我使用invalidateOptionsMenu();,该项目不会响应点击。如果您能帮助我解决我面临的类似问题,我将不胜感激。 *.com/questions/54756799/…
    • @AlitonOliveira 你应该通过检查你的标志变量状态将你的 item.setVisibility(false) 部分放在 onCreateOptionsMenu 方法中,你应该更改标志的布尔值和 invalidateOptionsMenu。它会起作用的。
    • setVisible 的文档指出您还应该调用setEnabled(false) 否则仍然可以通过它的快捷方式调用该项目
    【解决方案4】:

    就像 Nikolay 在 onPrepareOptionsMenu() 中所说的那样。

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

    这里有更详细的描述How can I refresh the ActionBar when onPrepareOptionsMenu switched menu entries?

    【讨论】:

      【解决方案5】:

      禁用某些项目:

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

      【讨论】:

      • 当我设置item.setVisible(false); 时,我的项目只有在我点击菜单本身时才会隐藏(三个点)。如果我使用invalidateOptionsMenu(); 某些项目不响应点击。如果您能帮助我解决我面临的类似问题,我将不胜感激。 *.com/questions/54756799/…
      【解决方案6】:

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

          @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。该怎么做?
      【解决方案7】:

      试试这个代码:

      @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(); 时,我总是可见的项目停止工作(我的意思是这些项目不响应点击)。如果您能帮助我解决我面临的类似问题,我将不胜感激。 *.com/questions/54756799/…
      【解决方案8】:

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

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

      【讨论】:

        【解决方案9】:

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

        getActivity().invalidateOptionsMenu();
        

        尝试这项工作就像对我的魅力一样。

        【讨论】:

          【解决方案10】:

          如果您有 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();
          }
          

          【讨论】:

            【解决方案11】:

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

            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
            }
            

            【讨论】:

              【解决方案12】:
              @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;
                  }
              

              【讨论】: