Как я могу изменить MenuItem в меню параметров на Android? - PullRequest
42 голосов
/ 17 ноября 2010

У меня есть меню параметров на моем Activity с MenuItem «Пуск». Когда выбран этот MenuItem, я бы хотел изменить меню, чтобы оно содержало MenuItem «Стоп». И, наконец, когда выбрано «Стоп», я бы хотел вернуться к «Старт».

Вот части моего кода, которые не работают. У меня есть и «Пуск», и «Стоп», перечисленные в mymenu.xml Мне, вероятно, следует удалить «Стоп» при создании меню:

public class MyActivity extends Activity {
    private boolean isStarted = false;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        menu.removeItem(R.id.stop);
        inflater.inflate(R.menu.mymenu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.start:
            isStarted = true;
            return true;
        case R.id.stop:
            isStarted = false;
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if(isStarted) {
            menu.removeItem(R.id.start);
            menu.add(R.id.stop);
        } else {
            menu.removeItem(R.id.stop);
            menu.add(R.id.start);
        }
        return true;
    }
}

Ответы [ 6 ]

96 голосов
/ 11 февраля 2011

Для этого типа операции я обычно выбираю не изменять пункты меню, а просто скрывать те, которые вам не нужны:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    menu.findItem(R.id.start).setVisible(!isStarted);
    menu.findItem(R.id.stop).setVisible(isStarted);
    return true;
}
20 голосов
/ 28 июля 2013

Flygenring ответ верный, но menu.findItem () является запаздывающим, и вызов его в onPrepareOptionsMenu (меню Menu) создает плохой пользовательский опыт. Лучше получить объект MenuItem один раз при создании меню, а затем просто вызывать setVisible каждый раз, когда меню появляется на экране:

    MenuItem mDynamicMenuItem;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        // Get dynamic menu item
        mDynamicMenuItem = menu.findItem(R.id.menu_item);
        return true;
    }

    // Prepare the Screen's standard options menu to be displayed. This is called right 
    // before the menu is shown, every time it is shown. You can use this method to
    // efficiently enable/disable items or otherwise dynamically modify the contents.
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        // Here is just a good place to update item
        mDynamicMenuItem.setVisible(isVisible);
        return true;
    }
6 голосов
/ 17 ноября 2010

Возможно, вам нужно вызвать super.onPrepareOptionsMenu после того, как вы закончите вносить изменения.Из документов :

Классы получения должны всегда вызывать реализацию базового класса.

3 голосов
/ 17 ноября 2010

Я получил решение. Вы в основном удаляете MenuItem при вызове removeItem(), тем самым также удаляя ссылку. Использование этого кода работает.

private boolean isStarted = false;

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case 1:
        isStarted = true;
        return true;
    case 0:
        isStarted = false;
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    if(isStarted) {
        menu.removeItem(1);
        menu.add(0, 0, 0, "Stop");
    } else {
        menu.removeItem(0);
        menu.add(0, 1, 0, "Start");
    }

    return super.onPrepareOptionsMenu(menu);
}

Вы должны создать MenuItem снова. Это также причина для ярлыка false. На самом деле вам не нужно MenuInflater, когда вы создаете Menu с помощью кода, поэтому также не требуется никакой файл меню XML.

1 голос
/ 11 сентября 2013

спасибо за информацию в этом посте, так как это решило мою проблему с ложными ярлыками в моем меню. Мне пришлось немного изменить его и получить окончательный код, который работает хорошо, как следует, в надежде, что он сэкономит кому-то еще время и разочарование. Это немного другое решение, но основным изменением, которое я сделал, было .setVisible для True или False, кроме того, решение i.shadrins наилучшим образом соответствовало моим потребностям.

    @Override
public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);

    if(loggedIn) 
    {
        logIn.setVisible(false);
        logOut.setVisible(true);
    } 
    else 
    {
        logIn.setVisible(true);
        logOut.setVisible(false);
    }
    return true;
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    logIn = menu.findItem(R.id.loggedOut);
    logOut = menu.findItem(R.id.loggedIn);
    return true;
}
0 голосов
/ 01 августа 2018

В Android 3.0 и выше, вы должны вызвать invalidateOptionsMenu () , чтобы запросить, чтобы система вызывала onPrepareOptionsMenu () . Затем вы можете изменить меню параметров в методе. Вы можете проверить Изменение пунктов меню во время выполнения раздела документации Android здесь https://developer.android.com/guide/topics/ui/menus#options-menu для получения более подробной информации.

...