15

我正在使用操作栏兼容性库。我试图从具有 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);
    }

}
4

8 回答 8

31

我在尝试在我正在做的应该在 Android 1.6 及更高版本上运行的应用程序上解决这个 openOptionsMenu 问题时遇到了同样的问题。根据 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();
    }
}
于 2013-07-27T22:35:13.197 回答
9

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

下面是取自 com.android.internal.policy.impl 的代码,它应该创建 optionsMenu 面板。如您所见,代码只是拒绝创建选项面板。不过,能力显然是有的。所以,回答你的问题:算了吧,谷歌不希望你再使用那个 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;
            }
        }
于 2013-06-06T15:33:32.990 回答
4

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

首先,我们需要定义是否需要以下 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...
}
于 2013-09-05T10:16:06.043 回答
3

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

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

祝你好运!

于 2012-04-19T14:57:37.667 回答
2

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

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

于 2012-09-24T21:52:37.833 回答
2

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

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;  
    }
于 2013-08-30T16:43:20.780 回答
0

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

这是我的做法:

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>

Activity
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);
}
于 2012-04-03T15:30:30.477 回答
0

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

toolBar.showOverflowMenu();
于 2016-06-20T08:32:43.977 回答