Функция openOptionsMenu не работает в ICS?

Я использую библиотеку совместимости панели действий. Я пытаюсь открыть меню параметров с помощью кнопки с функцией 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);
    }

}

person Richard    schedule 03.04.2012    source источник
comment
это сообщение [stackoverflow.com/questions/18937711/ мне подходит. [1]: stackoverflow.com /вопросы/18937711/   -  person Holding Fish    schedule 13.08.2014


Ответы (8)


Я не уверен, насколько это актуально, но этот форум сообщение, которое я нашел, похоже, отвечает на тот же вопрос, что и у вас.

Я надеюсь, что этот пост достаточно актуален, чтобы решить вашу проблему.

Удачи!

person Wottah    schedule 19.04.2012
comment
Как это решило проблему? Я не верю, что это действительно связано. - person htafoya; 30.08.2013
comment
Это связано, но ответы должны содержать ответ, а не просто ссылку на ответ на другом сайте. - person mhsmith; 20.11.2013
comment
На всякий случай, если кто-то все еще ищет, это реальный ответ в этом сообщении на форуме. Может быть, вы в команде Android должны сделать чертовски согласованный API, который работает на разных устройствах, чтобы мы не могли стрелять себе в НОГИ каждый раз, когда вы выпускаете и меняете поведение или добавить какую-то огромную новую вещь совершенно неожиданно. - person dipu; 30.07.2014
comment
Я до сих пор смотрю на это, и да, это не конец горя для меня. Я написал простое приложение-калькулятор. Недвижимость на экране драгоценна для меня, и я просто не могу иметь строку заголовка или панель действий. Первоначально я просто установил Target API на 2.2, и все работало, пока одно проклятое устройство не решило сделать кнопку меню плавающей, и она плавала прямо над знаком «+» в моем калькуляторе. Поэтому я переключил свой целевой API на 4.0, и с тех пор проблем не было. В Android больше нет возможности просто отображать меню. - person Edward Falk; 09.08.2015
comment
Во всяком случае, официальный ответ Марка Мерфи в этой ветке выглядит следующим образом: «Если у вас нет панели действий, у вас не может быть меню». Хотя, как ни странно, он работает на большинстве устройств, которые я пытаюсь поддерживать. - person Edward Falk; 09.08.2015
comment
И именно поэтому вы цитируете соответствующие части любого связанного контента! Ссылка не работает, и этот ответ теперь бесполезен. - person Eugen Pechanec; 26.12.2018

У меня была та же проблема, когда я пытался обойти эту вещь openOptionsMenu в приложении, которое я делал, которое должно работать на Android 1.6 и выше. После ответа Вернера Ван Белля я пришел к выводу, что мы можем найти обходной путь для решения проблемы. Поэтому я придумал следующий код, всегда красиво, когда люди не отмечают метод как окончательный, поэтому мы всегда можем его переопределить. Это идеально, если вы не хотите отказываться от таргетинга вашего приложения на последнюю версию 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();
    }
}
person tallicalord    schedule 27.07.2013
comment
Это ужасно! Кроме того, это единственное решение, которое работает. Спасибо! - person benkc; 21.11.2013
comment
Это не работает для моего приложения на устройстве 3.2, ориентированном на API 17. При нажатии кнопки я вызываю openOptionsMenu(), и метод в ответе выполняется. Но все же я не получаю меню опций. Интересно, как это работает для предыдущих комментаторов. Я что-то пропустил? Нужно ли нам переопределять какие-либо другие методы (onCreateOptionsMenu, onPrepareOptionsMenu)? - person MediumOne; 28.11.2013
comment
Как может это работать? Вы не можете просто изменить переменную конфигурации. Когда вы вызываете родительский элемент super.openOptionsMenu, он все равно будет извлекать свои собственные ресурсы, которые сообщат ему, что это снова большой экран. Поэтому мне интересно, действительно ли вы проверяли это? И если это так, и это сработало... тогда я почти уверен, что это не должно так работать, и оно может сломаться в любой момент. - person ; 19.12.2013
comment
Вернер Ван Белль, я согласен с вами, что это не должно работать. Но я проверил это сам, и на удивление меню снова отображается. - person Twinsen; 06.01.2014
comment
Магия! Этот ответ следует пометить как правильный. Спасибо - person jbc25; 15.01.2014
comment
Это работает, поскольку в коде Android они считывают это свойство, и если ваша целевая версия — Honeycomb или выше, и вы находитесь на большом экране, то он не вызывает методы меню (onCreate/PrepareOptionsMenu). Вы можете увидеть это в коде PhoneWindow.java в методе openPanel, есть следующий комментарий: Не открывать панель параметров для сотовых приложений на больших устройствах (приложение должно использовать панель действий для пунктов меню). - person Yoel Gluschnaider; 11.02.2014
comment
Это работает и на моем планшете Lollypop. Здорово! Замечания Вернера по поводу того, что Google навязывает разработчикам железную дорогу, были точны. - person Andrew S; 23.06.2015
comment
Спасибо! Я попробую. Не могли бы вы добавить несколько слов объяснения того, как и почему это работает? - person Edward Falk; 09.08.2015
comment
Я ненавижу, что Android сломал такую ​​​​базовую функциональность, как меню, что равносильно прихоти. Да, я знаю, что панель действий — это путь в будущее, но у меня есть веские причины, по которым я не могу ее использовать. Суть в том, что я лучше, чем разработчики Android, знаю, как мое приложение должно выглядеть и работать. Меню работало у меня нормально до недавнего времени, и теперь я получаю жалобы от платящих клиентов, что оно сломано. Все, что им нужно было сделать, это не сломать его. - person Edward Falk; 09.08.2015

Чтобы пролить свет на эту печальную разработку Google. Google, очевидно, хочет, чтобы все приняли новый ActionBar. Они могли бы добиться этого, сделав панель действий более простой в использовании, чем старая система меню. Однако это не то, как они планировали переход. Нет, они думали, что имеет смысл беспокоить программистов, делая старые меню невозможными для использования, но не обеспечивая надлежащей обратной совместимости.

Ниже приведен код, взятый из com.android.internal.policy.impl, который должен создать панель optionsMenu. Как видите, код просто отказывается создавать панель параметров. Хотя способности явно есть. Итак, чтобы ответить на ваш вопрос: забудьте об этом, Google больше не хочет, чтобы вы использовали эту панель параметров.

 // 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;
            }
        }
person Community    schedule 06.06.2013
comment
С Google снова кажется, что юзабилити — это оправдание, а не повестка дня. Молодцы, что раскопали это и просветили нас. - person Andrew S; 23.06.2015
comment
Панель действий совершенно проста в использовании, проблема в том, что у некоторых из нас есть вполне законные причины не использовать ее, и меню раньше работало у нас просто отлично. - person Edward Falk; 09.08.2015

Я также не могу понять принудительную блокировку использования кнопки меню. Однако следующий прием помог мне с отображением меню на «ограниченных» типах устройств.

Прежде всего нам нужно определить, нужен ли нам следующий хак или нет.

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...
}
person snuk182    schedule 05.09.2013

android:targetSdkVersion="10" в манифесте мне помог. openOptionsMenu() теперь работает как положено на ICS+. Кроме того, в нижней части экрана (на панели кнопок устройства) появляется кнопка меню «переполнение».

ps: я использую тему NoTitleBar (NoActionBar для SDK 11 и выше) + ViewPagerIndicator Джейка Уортона.

person deviant    schedule 24.09.2012

Это сработало для меня, мой код очень похож на ваш, и я хочу с помощью кнопки на панели действий открыть дополнительное меню:

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;  
    }
person htafoya    schedule 30.08.2013

Вы имеете в виду, что хотите показать кнопку с правой стороны панели действий?

Вот как я сделал свой:

рез/меню/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) MenuInflater в onCreateOptionsMenu 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);
}
person Mark Pazon    schedule 03.04.2012
comment
Нет, панель действий и меню раздуты и добавлены правильно. Это функция «openOptionsMenu()», вызываемая из кнопки, которая ничего не делает! - person Richard; 03.04.2012

Если вы используете свою настраиваемую панель инструментов, вы можете попробовать:

toolBar.showOverflowMenu();
person Saurabh Mishra    schedule 20.06.2016