Android'de menü öğesi metnini dinamik olarak değiştirme


212

onOptionsItemSelected(MenuItem item)Yöntemin dışından bir menü öğesinin başlığını değiştirmeye çalışıyorum .

Şunu zaten yapıyorum;

public boolean onOptionsItemSelected(MenuItem item) {
  try {
    switch(item.getItemId()) {
      case R.id.bedSwitch:
        if(item.getTitle().equals("Set to 'In bed'")) {
          item.setTitle("Set to 'Out of bed'");
          inBed = false;
        } else {
          item.setTitle("Set to 'In bed'");
          inBed = true;
        }
        break;
    }
  } catch(Exception e) {
    Log.i("Sleep Recorder", e.toString());
  }
  return true;
}

ancak bu yöntemin dışında belirli bir menü öğesinin başlığını değiştirmek istiyorum.


Yanıtlar:


127

JxDarkAngel'ın önerdiği gibi, bunu Faaliyetinizin herhangi bir yerinden çağırmak ,

invalidateOptionsMenu();

ve sonra geçersiz kılma:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  MenuItem item = menu.findItem(R.id.bedSwitch);
    if (item.getTitle().equals("Set to 'In bed'")) {
        item.setTitle("Set to 'Out of bed'");
        inBed = false;
    } else {
        item.setTitle("Set to 'In bed'");
        inBed = true;
    }
  return super.onPrepareOptionsMenu(menu);
}

çok daha iyi bir seçimdir. Cevabı https://stackoverflow.com/a/17496503/568197 adresinden kullandım.


En iyi çözüm. Çünkü bu tekerleği yeniden icat yerine android yöntemini geçersiz kılar.
Azlan Jamal

Bunun onPrepareOptionsMenu(), örneğin bir Etkinlik görüntülerken ve menü her görüntülendiğinde Android çerçevesi tarafından oldukça sık çağrıldığını unutmayın . Menünüz çok sık değişmezse bu çok etkili olmayabilir.
Mr-IDE

1
invalidateOptionsMenu()çağrılır onCreateOptionsMenu(), böylece güncelleme mantığını koyabilirsiniz onCreateOptionsMenu().
Bay-IDE

Bunu soruyla alakalı olacak şekilde düzenlerseniz, kabul edilen cevap olarak işaretlerim
Garbit

@Garbit, orijinal sorudaki kodunuzu kullanacak şekilde güncellendi!
Todd DeLand

375

Ben onCreateOptionsMenu içinde aldığınız Menu nesnesine aktivite içinde bir referans tutmak ve daha sonra ve gerektiği gibi değişiklik gerektiren MenuItem almak için kullanarak öneririz. Örneğin, aşağıdakilerin çizgileri boyunca bir şeyler yapabilirsiniz:

public class YourActivity extends Activity {

  private Menu menu;
  private String inBedMenuTitle = "Set to 'In bed'";
  private String outOfBedMenuTitle = "Set to 'Out of bed'";
  private boolean inBed = false;

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

    // Create your menu...

    this.menu = menu;
    return true;
  }

  private void updateMenuTitles() {
    MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
    if (inBed) {
      bedMenuItem.setTitle(outOfBedMenuTitle);
    } else {
      bedMenuItem.setTitle(inBedMenuTitle);
    }
  }

}

Alternatif olarak, menü her görüntülendiğinde menü öğelerini güncellemek için onPrepareOptionsMenu öğesini geçersiz kılabilirsiniz .


1
Android'in her zaman bu tür sorunlara daha zarif bir çözüm bulmasını bekliyorum. En basit cevaplar genellikle en iyisi gibi görünüyor - teşekkürler.
Steven Wolfe

12

bunu genel bir "Menü" nesnesi oluşturmak ve onCreateOptionMenu içinde atamak yapabilirsiniz

public class ExampleActivity extends AppCompatActivity
    Menu menu;

o zaman buraya atayın

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

Daha sonra gerekli öğeleri almak için atanmış Menu nesnesini kullanın

menu.findItem(R.id.bedSwitch).setTitle("Your Text");

5

Bir setOptionsTitle () yöntemi oluşturun ve sınıfınızda bir alan ayarlayın. Gibi:

String bedStatus = "Set to 'Out of Bed'";

...

public void setOptionsTitle(String status)
{
    bedStatus = status;

}

Şimdi menü doldurulduğunda, durumu durumunuzla değiştirin:

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

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }

Etkinlik oluşturulduktan sonra ayarlayabilmem gerekiyor. Bu nedenle bu iki yöntemin içinde değil
Garbit

Etkinliğiniz oluşturulduktan sonra herhangi bir noktada setOptionsTitle'ı arayın. Sanırım ne istediğini anlamıyorum çünkü "Aktivite oluşturulduktan sonra ayarlayabilmem gerekiyor", setContent (R.layout.id) adını verdikten sonra benim için anlamı ifade ediyor, seçenekleri değiştirmen gerekebilir menü görüntüler (setOptionsTitle () ile yapabilirsiniz - herhangi bir yöntemden, her yerde, her zaman).
Jack

Bu yaklaşım işe yarar olsa da, menüyü yöneten Menü nesnesi başlığın ne zaman değiştiğini bilmeyeceği ve bu nedenle başlık değiştiğinde, örneğin mizanpaj ve satır sonları gerektiğinde görevleri yerine getiremediği için önerilmez. .
Charles Harley

3

Geçersiz kılma onPrepareOptionsMenu kullanmanız daha iyi

menu.Clear ();
   if (TabActual == TabSelec.Anuncio)
   {
       menu.Add(10, 11, 0, "Crear anuncio");
       menu.Add(10, 12, 1, "Modificar anuncio");
       menu.Add(10, 13, 2, "Eliminar anuncio");
       menu.Add(10, 14, 3, "Actualizar");
   }
   if (TabActual == TabSelec.Fotos)
   {
       menu.Add(20, 21, 0, "Subir foto");
       menu.Add(20, 22, 1, "Actualizar");
   }
   if (TabActual == TabSelec.Comentarios)
   {
       menu.Add(30, 31, 0, "Actualizar");
   }

İşte bir örnek


Gerçekten, amaçlanan yaklaşımı kullanın. :) Menüye yerel bir referans yapmaya karar verirseniz, sanırım bağlam sızıntıları hakkında endişelenmeniz gerekir. Ya da olmayabilir. Ama kesinlikle bu yaklaşımla değil.
William T. Mallard

3

Bu gezinti öğemi alt gezinme öğemi karşılamak için kullanıyorum

BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");

2

Menü alanınızı bildirin.

private Menu menu;

OnCreateOptionsMenu () yöntemi şöyledir

public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
    try {
        getMenuInflater().inflate(R.menu.menu_main,menu);
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
    }
    return super.onCreateOptionsMenu(menu);
}

Aşağıda isim belirleyici etkinliğiniz olacaktır. Bir düğme tıklaması veya koşullu kod aracılığıyla

public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}

Bu benim için çalıştı.


0

Bana öyle geliyor ki, menü içeriğini yerel bir yöntem içinde değiştirmek istiyorsunuz ve bu yöntem herhangi bir zamanda, bir olay meydana geldiğinde veya etkinlik UI iş parçacığında çağrılıyor.

Neden geçersiz kılındığında onPrepareOptionsMenu'daki global değişkende Menü örneğini almıyorsunuz ve bu yönteminizi kullanmıyorsunuz. Bir olay meydana geldiğinde (düğme tıklaması gibi) veya etkinlik kullanıcı arabirimi iş parçacığında, işleyicide veya yürütme sonrası zaman uyumsuz görevde bu yöntemin çağrıldığından emin olun.

Değiştirmek istediğiniz bu menü öğesinin dizinini önceden bilmelisiniz. Menüyü temizledikten sonra, XML menüsünü şişirmeniz ve öğenizin adını veya simgesini güncellemeniz gerekir.


0

Statik olarak ayarlanmış başlığa ihtiyaç duyan insanlar için. Bu AndroidManifest.xml dosyasında yapılabilir

<activity
    android:name=".ActivityName"
    android:label="Title Text" >
</activity>

Seçenekler Menüsü Başlık Metni


3
Sorular dinamik değil, statik değil!
EngineSense

hala google arama geldi ve bana yardımcı oldu, gönderdiğin için teşekkürler
bruchowski

0

Parçanın menü simgesini değiştirmem gerekiyordu. Bu soruya Charles'ın cevabını biraz değiştirdim:

    private Menu top_menu;

    //...
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       setHasOptionsMenu(true);
       //...
       rootview = inflater.inflate(R.layout.first_content,null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_menu, menu);
        this.top_menu = menu;
    }


    // my procedure
    private void updateIconMenu() {
         if(top_menu!= null) {
             MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
             nav_undo.setIcon( R.drawable.back);
         }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.