openOptionsMenu function not working in ICS?

2019-01-12 05:42发布

Im using action bar compability library. Im trying to open the options menu from a button with openOptionsMenu() function but it does nothing.

Menu shows as usual when pressing the menu key on my phone. What is wrong here?

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

}

8条回答
兄弟一词,经得起流年.
2楼-- · 2019-01-12 05:59

I cannot understand the forcing blocking Menu button usage as well. However, the following trick helped me with showing a menu on "restricted" types of devices.

First of all we need to define, whether we require the following hack or not.

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

Then:

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

Don't forget to cleanup! (don't know if it's neccessary, but better to play kind)

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...
}
查看更多
疯言疯语
3楼-- · 2019-01-12 06:00

If you are using your custom toolbar, you can try:

toolBar.showOverflowMenu();
查看更多
狗以群分
4楼-- · 2019-01-12 06:02

This worked for me, my code is pretty similar to yours, and what I want to do is from a button in the action bar, open the overflow menu:

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;  
    }
查看更多
干净又极端
5楼-- · 2019-01-12 06:07

I'm not sure how relevant this is, but this forum post I found seems to be answerring the same question you have.

I hope this post is relevant enough to solve your problem.

Good luck!

查看更多
来,给爷笑一个
6楼-- · 2019-01-12 06:15

I was having the same problem trying to go around this openOptionsMenu thing on an app that I was doing that should run on Android 1.6 and up. Following the answer from Werner Van Belle I reached the conclusion that we could achieve a workaround to solve the problem. So I came up with the following code, it's always beatiful when people don't mark a method as final, so we can always override it. It's perfect if you don't want to give up on targeting your app to the latest api (android:targetSdkVersion="17"). I hope you guys like it. :)

@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();
    }
}
查看更多
在下西门庆
7楼-- · 2019-01-12 06:18

Do you mean you want to show a button on the right side of the action bar?

Here is how I did mine:

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) take note of the ActionBarActivity; 2) MenuInflater in onCreateOptionsMenu 3) onOptionsItemsSelected (I think you need to return 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);
}
查看更多
登录 后发表回答