【问题标题】:Show popup menu on `ActionBar` item click在“ActionBar”项目上显示弹出菜单点击
【发布时间】:2013-01-21 16:22:07
【问题描述】:

我有一个ActionBar,上面有一个操作项。单击操作项后,我想显示一个弹出菜单。 我实现了这个方法,但我想将它锚定到操作项或ActionBar,而不是布局中的任何视图。如何从MenuItem 获得某种视图来锚定它?

public boolean onOptionsItemSelected(MenuItem item) {
    PopupMenu popupMenu = new PopupMenu(this, ??????); // What view goes here?
    popupMenu.inflate(R.menu.counters_overflow);
    popupMenu.show();
    // ...
    return true;
}

【问题讨论】:

标签: android android-actionbar popupmenu


【解决方案1】:

所以我终于找到了解决方案。当您想将弹出菜单锚定到 ActionBar 中的 ActionItem 时,您需要找到呈现 ActionItem 的视图。 使用 findViewById() 的简单查找视图,其中 id 与 xml 中菜单项的 id 相同。

显示弹出窗口:

public boolean onOptionsItemSelected(MenuItem item) {
    // ...

    View menuItemView = findViewById(R.id.menu_overflow); // SAME ID AS MENU ID
    PopupMenu popupMenu = new PopupMenu(this, menuItemView); 
    popupMenu.inflate(R.menu.counters_overflow);
    // ...
    popupMenu.show();
    // ...
    return true;
}

菜单:

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

     ....

     <item
    android:id="@+id/menu_overflow"
    android:icon="@drawable/ic_overflow"
    android:showAsAction="ifRoom"
    android:title="@string/menu_overflow"/>

     ....

</menu>

如果菜单项不可见(溢出),则它不起作用。 findViewById 返回 null,因此您必须检查这种情况并锚定到另一个视图。

【讨论】:

  • findViewById(R.id.menu_overflow) 给我一个空视图
  • findViewById(R.id.menu_overflow) 如果您在非活动根视图中找到,则返回 null。使用 Activity.findViewById(R.id.menu_overflow) 一切正常 =))
  • 是否可以在 popupMenu 中的特定项目之间添加分隔符?
  • 我收到此错误:MenuPopupHelper 不能在没有锚的情况下使用
  • 不工作。没有锚错误就无法使用获取
【解决方案2】:

接受的答案对我不起作用,所以我通过反复试验找到了问题。

public boolean onOptionsItemSelected(MenuItem item) 
{
    View menuItemView = findViewById(item.getItemId()); 
    showPopupMenu(menuItemView)

    return true;
}

private void showPopupMenu(View anchor)
{
    PopupMenu popup = new PopupMenu(this, anchor);
    popup.getMenuInflater().inflate(R.menu.my_popup_menu, popup.getMenu());
    popup.show();
}

这里的关键是,onOptionsItemSelected(MenuItem item) 中的item 必须显示在 ActionBar 上。如果item是你按下ActionBar右上角的三个垂直点时出现的项目之一,那么你的应用就会崩溃。

【讨论】:

    【解决方案3】:

    请试试这个..

      @Override
    public boolean onOptionsItemSelected(MenuItem item){
        String str=item.getTitle().toString(); 
        Toast.makeText(getBaseContext(), str,Toast.LENGTH_LONG). show();
    
        View view=findViewById(item.getItemId()); 
        switch(view.getId()){
            case Menu.FIRST:
                showPopup(view); // calling method
        }
    
        return super.onOptionsItemSelected(item);
    }   
    
    // custom method
    private void showPopup(final View view) {
        PopupMenu popupMenu = new PopupMenu(view.getContext(), view);
        popupMenu.getMenu().add(0, 0, Menu.NONE, "Item 1");
        popupMenu.getMenu().add(0, 1, Menu.NONE, "Item 2");
        popupMenu.getMenu().add(0, 2, Menu.NONE, "Item 3");
        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    Toast.makeText(view.getContext(), item.getTitle() + "clicked", Toast.LENGTH_SHORT).show();
                    return true;
                }
            });
        popupMenu.show();
    }
    

    【讨论】:

      【解决方案4】:

      除了接受的答案之外,在每次调用 onOptionsItemSelected() 方法时重新膨胀弹出窗口的问题可以通过只执行一次并且只显示我们想要的次数来简化。
      (这甚至适用于在运行时通过 Menu Layout Inflater 膨胀的自定义工具栏。请记住,获取菜单项视图的 findViewById() 只能在视图实际出现在屏幕上时返回非空值,即应该在工具栏/操作栏上可见。

      注意:如果视图预设在工具栏/操作栏的溢出菜单中,则视图可能仅在至少调用一次溢出菜单后才会膨胀 - 使用 3 个点?)

      public class SomeActivity{
          
          private PopupMenu popup;
          .... // some code of the activity
      
      @Override
          public boolean onOptionsItemSelected(@NonNull MenuItem item) {
              int menuItem = item.getItemId();
              switch (menuItem) {
                  case R.id.tb_menu_plus:
                      View menuItemView = findViewById(R.id.tb_menu_plus);
                      if(popup == null) {
                          popup = new PopupMenu(this, menuItemView);
                          popup.inflate(R.menu.dropdown_popup_menu);
                      }
                      popup.show();
                      return true;
              }
              return super.onOptionsItemSelected(item);
          }
      
      

      【讨论】:

        【解决方案5】:
        public boolean onOptionsItemSelected(MenuItem item) {
            final View addView = getLayoutInflater().inflate(R.layout.add, null);
        
                    new AlertDialog.Builder(this).setTitle("Add a Word").setView(addView)
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int whichButton) {
                                    addWord((TextView) addView.findViewById(R.id.title));
                                }
                            }).setNegativeButton("Cancel", null).show();
        return (super.onOptionsItemSelected(item));
            }
        

        在这里获取完整的源代码..

        http://vimaltuts.com/android-tutorial-for-beginners/android-action-bar-tab-menu-example

        【讨论】:

        • 抱歉,我确实想为单击 ActionItem 时创建的 PopupMenu 找到正确的用法。没有变通办法。
        • 问题是关于 PopupMenu 而不是 AlertDialog。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多