Cara mengubah teks item menu secara dinamis di Android

212

Saya mencoba mengubah judul item menu dari luar onOptionsItemSelected(MenuItem item)metode.

Saya sudah melakukan yang berikut;

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

namun saya ingin dapat mengubah judul item menu tertentu di luar metode ini.

Garbit
sumber
stackoverflow.com/a/32072318/1651286 harus menjadi jawaban yang diterima
Akhil Dad

Jawaban:

127

Seperti yang disarankan JxDarkAngel, menyebutnya dari mana saja dalam Aktivitas Anda ,

invalidateOptionsMenu();

dan kemudian mengesampingkan:

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

adalah pilihan yang jauh lebih baik. Saya menggunakan jawaban dari https://stackoverflow.com/a/17496503/568197

Todd DeLand
sumber
Solusi terbaik. Karena yang satu ini menimpa metode android alih-alih menemukan kembali roda.
Azlan Jamal
Perhatikan saja bahwa onPrepareOptionsMenu()ini cukup sering dipanggil oleh kerangka kerja Android, misalnya saat menampilkan Aktivitas dan setiap kali menu ditampilkan. Jadi ini mungkin tidak terlalu efisien, jika menu Anda tidak terlalu sering berubah.
Mr-IDE
1
invalidateOptionsMenu()juga akan menelepon onCreateOptionsMenu(), sehingga Anda dapat memasukkan logika pembaruan onCreateOptionsMenu().
Mr-IDE
Jika Anda mengedit ini agar relevan dengan pertanyaan, saya akan menandainya sebagai jawaban yang diterima
Garbit
@ Garbit diperbarui untuk menggunakan kode Anda dari pertanyaan asli!
Todd DeLand
375

Saya akan menyarankan menyimpan referensi dalam aktivitas ke objek Menu yang Anda terima di onCreateOptionsMenu dan kemudian menggunakannya untuk mengambil MenuItem yang memerlukan perubahan saat dan ketika Anda membutuhkannya. Misalnya, Anda dapat melakukan sesuatu di sepanjang baris berikut ini:

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

}

Atau, Anda dapat mengganti onPrepareOptionsMenu untuk memperbarui item menu setiap kali menu ditampilkan.

Charles Harley
sumber
1
Saya selalu berharap Android memiliki solusi yang lebih elegan untuk masalah seperti ini. Tampaknya jawaban yang paling sederhana seringkali yang terbaik - terima kasih.
Steven Wolfe
12

Anda dapat melakukan ini dengan membuat objek "Menu" global kemudian menetapkannya di onCreateOptionMenu

public class ExampleActivity extends AppCompatActivity
    Menu menu;

kemudian tetapkan di sini

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

Kemudian, gunakan objek Menu yang ditetapkan untuk mendapatkan item yang diperlukan

menu.findItem(R.id.bedSwitch).setTitle("Your Text");
Pranav Raut
sumber
5

Buat metode setOptionsTitle () dan setel bidang di kelas Anda. Seperti:

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

...

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

}

Sekarang ketika menu terisi, ubah judul menjadi apa pun status Anda:

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

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }
Mendongkrak
sumber
Saya harus dapat mengaturnya setelah aktivitas telah diberikan. Jadi karena itu tidak ada di dalam dua metode
Garbit
Panggil setOptionsTitle kapan saja setelah aktivitas Anda diberikan. Saya kira saya tidak mengerti apa yang Anda inginkan karena "Saya harus dapat mengaturnya setelah aktivitas telah diberikan" berarti bagi saya setelah Anda memanggil setContent (R.layout.id), Anda mungkin perlu mengubah opsi apa yang ada tampilan menu (yang dapat Anda lakukan dengan setOptionsTitle () - dari metode apa pun, di mana saja, kapan saja).
Jack
Meskipun pendekatan ini berfungsi, itu tidak akan direkomendasikan sebagai objek Menu yang mengelola menu tidak akan tahu kapan judul telah berubah dan oleh karena itu tidak dapat melakukan tugas-tugas yang mungkin perlu ketika judul berubah, misalnya tata letak dan jeda baris .
Charles Harley
3

Anda lebih baik menggunakan override onPrepareOptionsMenu

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

Berikut sebuah contoh

JxDarkAngel
sumber
Memang, gunakan pendekatan yang dimaksud. :) Jika Anda memutuskan untuk menyimpan referensi lokal ke menu Anda akan perlu khawatir tentang kebocoran konteks saya akan berpikir. Atau mungkin tidak. Tetapi tentu saja tidak dengan pendekatan ini.
William T. Mallard
3

Saya menggunakan kode ini untuk menyesuaikan item navigasi bawah saya

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

Nyatakan bidang menu Anda.

private Menu menu;

Berikut ini adalah metode onCreateOptionsMenu ()

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

Mengikuti akan menjadi aktivitas setter nama Anda. Baik melalui klik tombol atau melalui kode kondisional

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

Ini berhasil untuk saya.

hyperCoder
sumber
0

Sepertinya saya ingin mengubah konten menu di dalam metode lokal, dan metode ini dipanggil kapan saja, setiap kali suatu peristiwa terjadi, atau di utas aktivitas UI.

Mengapa Anda tidak mengambil instance Menu dalam variabel global di onPrepareOptionsMenu ketika ini ditimpa dan digunakan dalam metode Anda ini. Pastikan bahwa metode ini dipanggil setiap kali suatu peristiwa terjadi (seperti klik tombol), atau di utas aktivitas UI, handler atau tugas-tugas async pasca-eksekusi.

Anda harus tahu sebelumnya indeks item menu ini yang ingin Anda ubah. Setelah menghapus menu, Anda perlu mengembang menu XML dan memperbarui nama atau ikon item Anda.

Abhinav Saxena
sumber
0

Bagi orang yang membutuhkan judul diatur secara statis. Ini dapat dilakukan di AndroidManifest.xml

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

Opsi Menu Judul Teks

moberme
sumber
3
Pertanyaan untuk dinamis, bukan statis!
EngineSense
masih muncul di pencarian google dan membantu saya, terima kasih telah memposting
bruchowski
0

Saya perlu mengubah ikon menu untuk fragmen. Saya sedikit mengubah jawaban Charles untuk pertanyaan ini:

    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);
         }
    }
Almaz Vildanov
sumber