android: programowa zmiana elementów menu opcji


89

Czy jest możliwa programowa zmiana pozycji menu opcji? Czy ktoś może podać mi przykład?

Chcę też wyłączyć pewne elementy, aby nie nasłuchiwały kliknięć, czy to możliwe?

Odpowiedzi:


212

Dla każdego trzeba dynamicznie zmieniać opcje menu:

private Menu menu;

// ...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    this.menu = menu;
    getMenuInflater().inflate(R.menu.options, menu);
    return true;
}

// ...

private void hideOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(false);
}

private void showOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(true);
}

private void setOptionTitle(int id, String title)
{
    MenuItem item = menu.findItem(id);
    item.setTitle(title);
}

private void setOptionIcon(int id, int iconRes)
{
    MenuItem item = menu.findItem(id);
    item.setIcon(iconRes);
}

8
Jedynym zastrzeżeniem jest to, że musisz się upewnić, że menuzostało ustawione, zanim spróbujesz się MenuItemz tego wydostać. Na przykład, jeśli masz coś podobnego actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS), karty są ładowane przed menu, więc wywołanie hideOption/ showOptionwithin onTabSelectedskutkuje wyjątkiem wskaźnika o wartości null.
SaltyNuts

Kiedy używam item.setVisible(false);, element zostaje ukryty tylko wtedy, gdy kliknę samo menu. Jeśli używam invalidateOptionsMenu();elementu, nie reaguję na kliknięcie. Doceniam, gdybyś mógł mi pomóc w podobnej sprawie, z którą się zmagam. stackoverflow.com/questions/54756799/…
Aliton Oliveira

@AlitonOliveira powinieneś umieścić swoją część item.setVisibility (false) wewnątrz metody onCreateOptionsMenu, sprawdzając status zmiennej flagi i powinieneś zmienić wartość bool swojej flagi i invalidateOptionsMenu. to będzie działać.
Kidus Tekeste

Dokumentacja setVisiblestwierdza, że ​​należy również zadzwonić, w setEnabled(false)przeciwnym razie przedmiot nadal będzie można wywołać za pomocą jego skrótu
Florian Walther

34

menu.xml

  <item 
    android:id="@+id/item1"
    android:title="your Item">
  </item>

umieść w swoim pliku java

  public void onPrepareOptionsMenu(Menu menu) {

    menu.removeItem(R.id.item1);
}

To jest ten, którego szukałem, ponieważ chcę podjąć decyzję raz w czasie wykonywania, ale nie muszę później zmieniać opcji. Użyłem: @Override public boolean onPrepareOptionsMenu (menu menu) {if (! ShowItemName) {menu.removeItem (R.id.itemname); } return true; }
notmystyle


7

Jeśli muszę zmienić zawartość mojego menu opcji, wykonuję to podczas onMenuOpened (). Dzięki temu mogę sprawdzić stan pracy w chwili, gdy użytkownik uzyskuje dostęp do menu.

public boolean onMenuOpened(int featureid, Menu menu)
    {
        menu.clear();
        if (!editable)
        {
            MenuItem itemAdd = menu.add(0, REASSIGN, Menu.NONE, context.getString(R.string.reassign));
            MenuItem itemMod = menu.add(1, EDIT, Menu.NONE, context.getString(R.string.modify));
            MenuItem itemDel = menu.add(2, DELETE, Menu.NONE, context.getString(R.string.delete));
            itemAdd.setShortcut('0', 'a');
            itemMod.setShortcut('1', 'm');
            itemDel.setShortcut('2', 'd');
        }
        else
        {
            MenuItem itemSave = menu.add(3, SAVE, Menu.NONE, context.getString(R.string.savechanges));
            itemSave.setShortcut('0', 'S');
        }


        return true;
    }

Kilka słów komentarza. onMenuOpened jest wywoływany dwukrotnie. Zmienna menu za pierwszym razem jest pusta, zmienna menu za drugim razem jest przygotowana do użycia. Zawsze używam klauzuli „if”, aby sprawdzić, czy zmienna menu nie jest null.
Ksiądz Pistolet

7

Aby wyłączyć określone elementy:

MenuItem item = menu.findItem(R.id.ID_ASSING_TO_THE_ITEM_IN_MENU_XML);
item.setEnabled(false);

Po ustawieniu item.setVisible(false);moja pozycja zostaje ukryta dopiero po kliknięciu samego menu (trzy kropki). Jeśli używam invalidateOptionsMenu();niektórych elementów, nie reaguję na kliknięcie. Doceniam, gdybyś mógł mi pomóc w podobnej sprawie, z którą się zmagam. stackoverflow.com/questions/54756799/…
Aliton Oliveira

4

korzystając z poniższych wierszy, które zrobiłem, aby dodać wartości w menu

getActivity().invalidateOptionsMenu();

spróbuj tej pracy jak urok dla mnie.


3

Wypróbuj ten kod:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu=menu;
    updateMenuItems(menu);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.document_list_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    if (item.getItemId() == android.R.id.home) {
        onHomeButtonPresssed();
    }else if (item.getItemId() == R.id.action_delete) {
        useCheckBoxAdapter=false;
        deleteDocuments();
    } else if (item.getItemId() == R.id.share) {
        useCheckBoxAdapter=false;
        shareDocuments();
    } else if (item.getItemId() == R.id.action_tick) {
        useCheckBoxAdapter=true;
        onShowCheckboxes();
    }
    updateMenuItems(menu);
    return true;
}

private void updateMenuItems(Menu menu){
    if (useCheckBoxAdapter && menu != null) {
        menu.findItem(R.id.action_delete).setVisible(true);
        menu.findItem(R.id.share).setVisible(true);
        menu.findItem(R.id.action_tick).setVisible(false);
    } else {
        menu.findItem(R.id.action_delete).setVisible(false);
        menu.findItem(R.id.share).setVisible(false);
        menu.findItem(R.id.action_tick).setVisible(true);
    }
    invalidateOptionsMenu();
}

Kiedy używam invalidateOptionsMenu();, moje zawsze widoczne elementy przestają działać (mam na myśli, że elementy nie reagują na kliknięcie). Doceniam, gdybyś mógł mi pomóc w podobnej sprawie, z którą się zmagam. stackoverflow.com/questions/54756799/…
Aliton Oliveira

2

Możesz zrobić coś prostego, tak jak ja. Po dotknięciu elementu menu zmień tekst na taki, który jest potrzebny. Musiałem wyłączyć i włączyć dźwięk, a także móc wykonać akcję, dotykając go. Oto mój kod:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.audioOn:
        audioOn = !audioOn;
        if (audioOn)
            item.setTitle("Audio Off");
        else
            item.setTitle("Audio On");
        return true;

    case R.id.touchOn:
        touchOn = !touchOn;
        if (touchOn)
            item.setTitle("Touch Off");
        else
            item.setTitle("Touch On");
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

audioOn i touchOn to wartości logiczne sprawdzane w innych częściach kodu. Mam nadzieję że to pomoże.


Jak mogę to zrobić dynamicznie. Mam na myśli ... wywołanie usługi sieciowej po wybraniu elementu opcji, a następnie po jej pomyślnej odpowiedzi ... ponowne wywołanie onCreateOptionsMenu. Jak to zrobić?
Narendra Singh

1

możesz wykonać swoje zadanie, po prostu implementując, jak poniżej:

private Menu menu;

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.drive_menu, menu);
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu = menu;
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_toggle_grid) {
        handleMenuOption(id);
        return true;

    } else if(id == R.id.action_toggle_list){
        handleMenuOption(id);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void handleMenuOption(int id) {
    MenuItem item = menu.findItem(id);
    if (id == R.id.action_toggle_grid){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_list).setVisible(true);
    }else if (id == R.id.action_toggle_list){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_grid).setVisible(true);
    }
}

1

W przypadku, gdy masz BottomBar:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    if (mBottomBar.getCurrentTabId() == R.id.tab_more) {
        getMenuInflater().inflate(R.menu.more_menu, menu);
    }

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.preferences:
            startActivity(new Intent(this, PreferenceActivity.class));
            break;
    }

    return super.onOptionsItemSelected(item);
}

Następnie wystarczy zadzwonić:

@Override
public void onBottomBarClick(int tabId) {
    supportInvalidateOptionsMenu();
}

1

Kod Kotlin do uzyskiwania dostępu do paska narzędzi Opcje Elementy menu programowo i zmiana tekstu / ikony, ..:

1-Mamy naszą pozycję menu w pliku pozycji menu, takim jak: menu.xml, przykładowy kod do tego:

 <?xml version="1.0" encoding="utf-8"?> 
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/balance"
      android:title="0"
      android:orderInCategory="100"
      app:showAsAction="always" />
 </menu>

2- Zdefiniuj zmienną dostępu do obiektu menu w klasie:

var menu: Menu? = null

3 - zainicjuj go w onCreateOptionsMenu:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    this.menu = menu
    return true
}

4- Uzyskaj dostęp do pozycji menu w kodzie lub zabawie:

private fun initialBalanceMenuItemOnToolbar() {
var menuItemBalance = menu?.findItem(R.id.balance)
    menuItemBalance?.title = Balance?.toString() ?: 0.toString()
    // for change icon : menuWalletBalance?.icon
}

1
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.calendar, menu);
        if(show_list == true) {         

        if(!locale.equalsIgnoreCase("sk")) menu.findItem(R.id.action_cyclesn).setVisible(false);

        return true;
    }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.