Функция openOptionsMenu не работает в ICS? - PullRequest
15 голосов
/ 03 апреля 2012

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

}

Ответы [ 8 ]

32 голосов
/ 28 июля 2013

У меня возникла та же проблема, пытаясь обойти эту вещь 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();
    }
}
9 голосов
/ 06 июня 2013

Чтобы пролить свет на это печальное развитие событий от Google. Google, очевидно, желает всем принять новый ActionBar. Они могли бы добиться этого, сделав 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;
            }
        }
4 голосов
/ 05 сентября 2013

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

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

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...
}
3 голосов
/ 19 апреля 2012

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

Я надеюсь, что это сообщение достаточно уместно для решенияВаша проблема.

Удачи!

2 голосов
/ 30 августа 2013

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

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;  
    }
2 голосов
/ 25 сентября 2012

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

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

0 голосов
/ 20 июня 2016

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

toolBar.showOverflowMenu();
0 голосов
/ 03 апреля 2012

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

Вот как я это сделал:

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