【问题标题】:openOptionsMenu function not working in ICS?openOptionsMenu 功能在 ICS 中不起作用?
【发布时间】:2012-04-17 06:55:06
【问题描述】:

我正在使用操作栏兼容性库。我试图从一个带有 openOptionsMenu() 函数的按钮打开选项菜单,但它什么也没做。

按手机上的菜单键时,菜单照常显示。这里有什么问题?

public class ReadActivity extends ActionBarActivity {

    ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        boolean value;
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.read, menu);
        value = super.onCreateOptionsMenu(menu);

        if (Helper.SupportsNewApi()) {
            getActionBar().hide();
        } else {
            ((View) ((LinearLayout) findViewById(R.id.actionbar_compat))
                    .getParent()).setVisibility(View.GONE);
        }

        return value;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            break;
        case R.id.menu_search:
            // Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show();
            break;
        case R.id.menu_bookmark:
            // selectText();
            // setFullScreen(false);
            break;
        case R.id.menu_day_night_mode:
            break;
        case R.id.menu_settings:
            break;
        case R.id.menu_zoom_in:
            showOverlay(false);
            break;
        case R.id.menu_zoom_out:
            showOverlay(false);
            break;
        case R.id.menu_table_of_contents:
            Intent tocIntent = new Intent(this, TocActivity.class);
            int GET_SECTION_REFERENCE = 1;
            startActivityForResult(tocIntent, GET_SECTION_REFERENCE);
            break;
        case R.id.menu_overflow:
            Toast.makeText(this, "Tapped overflow", Toast.LENGTH_SHORT).show();

            //closeOptionsMenu();
            openOptionsMenu(); //tried the below aswell, no results
            //getWindow().openPanel(Window.FEATURE_OPTIONS_PANEL, null);
            break;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override //disable volume buttons
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (!menuShown && (keyCode == 25 || keyCode == 24)) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        Log.d(tag, "Keycode is = "+keyCode);
        if (keyCode == 82) {
            if (!menuShown) {
                //openOptionsMenu();
                showOverlay(true);
            } else {
                showOverlay(false);
            }


                    //don't want it to open when pressing menu
            return true;
        } else if (keyCode == 4 && menuShown) {
            showOverlay(false);
            return true;
        } else if (keyCode == 25 && !menuShown) {
            prevPage();
            return true;
        } else if (keyCode == 24 && !menuShown) {
            nextPage();
            return true;
        }

        return super.onKeyUp(keyCode, event);
    }

}

【问题讨论】:

标签: android android-menu android-actionbar


【解决方案1】:

您的意思是要在操作栏的右侧显示一个按钮?

这是我的做法:

res/menu/main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_share"
    android:title="Logout"
    android:icon="@android:drawable/ic_lock_power_off"
    android:orderInCategory="1"
    android:showAsAction="always" />
</menu>

活动
1)注意ActionBarActivity; 2)onCreateOptionsMenu中的MenuInflater 3)onOptionsItemsSelected(我认为你需要返回super.onOptionsItemSelected(item))

public class BaseActivity extends ActionBarActivity {
    ....

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);

    return true;
}
....
@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.menu_share:


       //Do something
        break;
    }

    return super.onOptionsItemSelected(item);
}

【讨论】:

  • 操作栏和菜单没有正确膨胀和添加。这是从一个什么都不做的按钮调用的“openOptionsMenu()”函数!
【解决方案2】:

我不确定这有多相关,但我发现 this 论坛帖子似乎回答了您的相同问题。

我希望这篇文章足够相关,可以解决您的问题。

祝你好运!

【讨论】:

  • 这是如何解决问题的?我不相信它真的相关。
  • 它是相关的,但答案应该包含一个答案,而不仅仅是指向另一个站点上的答案的链接。
  • 以防万一有人还在看,这是该论坛帖子上的真正答案“也许您在 Android 团队中应该制作一个可跨设备工作的令人讨厌的一致 API,这样我们就无法自爆每次你释放和改变行为或突然添加一些巨大的新事物时的脚。”
  • 我还在看它,是的,这对我来说没有尽头的悲伤。我写了一个简单的计算器应用程序。屏幕空间对我来说很宝贵,我根本没有标题栏或操作栏。最初我只是将 Target API 设置为 2.2,然后一切正常,直到一个该死的设备决定将菜单按钮设为浮动按钮,它就在我的计算器中的“+”号上浮动。所以我将我的目标 API 切换到 4.0,此后麻烦不断。根本无法在 Android 中仅显示菜单。
  • 无论如何,Mark Murphy 在该线程中的官方回答似乎是“如果你没有操作栏,那么你就没有菜单。”虽然奇怪的是,它似乎可以在我尝试支持的大多数设备上运行。
【解决方案3】:
清单中的

android:targetSdkVersion="10" 帮助了我。 openOptionsMenu() 现在在 ICS+ 上按预期工作。此外,屏幕底部(在设备按钮面板上)出现了“溢出”菜单按钮。

ps:我使用 NoTitleBar 主题(NoActionBar 用于 sdk 11 及更高版本)+ViewPagerIndicator by Jake Wharton。

【讨论】:

    【解决方案4】:

    为了阐明谷歌的这一悲惨发展。谷歌显然希望每个人都接受新的 ActionBar。他们可以通过使 ActionBar 比旧的菜单系统更易于使用来实现这一点。然而,这不是他们计划过渡的方式。不,他们认为通过使旧菜单无法使用但不提供适当的向后兼容性来骚扰程序员是有意义的。

    下面是取自 com.android.internal.policy.impl 的代码,它应该创建 optionsMenu 面板。如您所见,代码只是拒绝创建选项面板。不过,能力显然是有的。所以,回答你的问题:算了,Google 不希望你再使用那个 optionsPanel。

     // Don't open an options panel for honeycomb apps on xlarge devices.
     // (The app should be using an action bar for menu items.)
     if (st.featureId == FEATURE_OPTIONS_PANEL) {
                Context context = getContext();
                Configuration config = context.getResources().getConfiguration();
                boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
                        Configuration.SCREENLAYOUT_SIZE_XLARGE;
                boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
                        android.os.Build.VERSION_CODES.HONEYCOMB;
    
                if (isXLarge && isHoneycombApp) {
                    return;
                }
            }
    

    【讨论】:

    • Google 似乎再次认为可用性是借口,而不是议程。很好地挖掘了这一点并启发了我们。
    • Action Bar 非常易于使用,问题是我们中的一些人有完全正当的理由不使用它,而且菜单以前对我们来说也很好用。
    【解决方案5】:

    我在尝试在应用程序上解决这个 openOptionsMenu 问题时遇到了同样的问题 我正在做的应该在 Android 1.6 及更高版本上运行。根据 Werner Van Belle 的回答,我得出结论,我们可以找到一种解决方法来解决问题。 所以我想出了下面的代码,当人们不将方法标记为 final 时总是很漂亮,所以我们总是可以覆盖它。如果您不想放弃将您的应用程序定位到最新的 api (android:targetSdkVersion="17"),这是完美的。我希望你们喜欢。 :)

    @Override
    public void openOptionsMenu() {
    
        Configuration config = getResources().getConfiguration();
    
        if((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) 
                > Configuration.SCREENLAYOUT_SIZE_LARGE) {
    
            int originalScreenLayout = config.screenLayout;
            config.screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
            super.openOptionsMenu();
            config.screenLayout = originalScreenLayout;
    
        } else {
            super.openOptionsMenu();
        }
    }
    

    【讨论】:

    • 太糟糕了!这也是唯一有效的解决方案。谢谢!
    • 这不适用于我在面向 API 17 的 3.2 设备上的应用程序。单击按钮时,我调用 openOptionsMenu() 并执行答案中的方法。但我仍然没有得到选项菜单。我想知道它对以前的评论者是如何工作的。我错过了什么吗?我们是否需要覆盖任何其他方法(onCreateOptionsMenu、onPrepareOptionsMenu)?
    • 如何 工作?您不能简单地修改配置变量。当您调用父 super.openOptionsMenu 时,它仍然会检索自己的资源,这会告诉它又是一个大屏幕。所以我想知道你是否真的测试过这个?如果是这样并且它确实有效......那么我很确定它不应该那样工作,它可能随时都会中断。
    • 魔术!此答案应标记为正确答案。谢谢
    • 我讨厌Android破坏了菜单这样的基本功能,这相当于一时兴起。是的,我知道 Action Bar 是未来的发展方向,但我有正当理由不能使用它。最重要的是,我比 Android 开发人员更了解我的应用程序的外观和感觉。直到最近,菜单对我来说还不错,现在我收到了付费顾客的抱怨,因为它已经坏了。他们所要做的就是打破它。
    【解决方案6】:

    这对我有用,我的代码与你的非常相似,我想做的是从操作栏中的按钮打开溢出菜单

    public boolean onOptionsItemSelected(MenuItem item) {  
            switch (item.getItemId()) {  
            case R.id.menu_home_about:  
                dialog = new Dialog(this);
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setContentView(R.layout.customdialog);
                dialog.show();
                break;
    
                default:
    
            case R.id.menu_home_refresh:
                updateLists(true);
                break;
    
            case R.id.menu_home_menu:
                new Handler().postDelayed(new Runnable() {
                    public void run() {                
                        openOptionsMenu();        
                    }
                }, 0); 
                return true;
    
            }
            return false;  
        }
    

    【讨论】:

      【解决方案7】:

      我也无法理解强制阻止菜单按钮的使用。但是,以下技巧帮助我在“受限”类型的设备上显示菜单。

      首先,我们需要定义是否需要以下 hack。

      boolean requireDirtyMenuButtonHack = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && (activity.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) > 0;
      

      然后:

      protected final OnClickListener mMenuButtonClickListener = new OnClickListener() {
      
          @Override
          public void onClick(View v) {
              if (requireDirtyMenuButtonHack) {
                  Configuration config = getContext().getResources().getConfiguration();
                  config.screenLayout &= ~Configuration.SCREENLAYOUT_SIZE_XLARGE;
                  config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
              }
      
              getActivity().openOptionsMenu();
          }
      };
      

      别忘了清理! (不知道有没有必要,但最好玩善良)

      public void onPrepareOptionsMenu(Menu menu) {
          if (requireDirtyMenuButtonHack) {
              Configuration config = getContext().getResources().getConfiguration();
              config.screenLayout &= ~Configuration.SCREENLAYOUT_SIZE_LARGE;
              config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
          }
      
          //do the preparing...
      }
      

      【讨论】:

        【解决方案8】:

        如果您使用的是自定义工具栏,可以尝试:

        toolBar.showOverflowMenu();
        

        【讨论】:

          猜你喜欢
          • 2017-05-22
          • 2011-02-16
          • 2012-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多