Bagaimana cara menyembunyikan item menu di actionbar?


346

Saya memiliki panel tindakan dengan menuitem. Bagaimana saya bisa menyembunyikan / menampilkan item menu itu?

Inilah yang saya coba lakukan:

MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();

Jawaban:


484

Dapatkan MenuItemmenunjuk ke item tersebut, panggil setVisibleuntuk menyesuaikan visibilitasnya dan kemudian panggil invalidateOptionsMenu()aktivitas Anda sehingga menu ActionBar disesuaikan.

Pembaruan: A MenuItembukan tampilan biasa yang merupakan bagian dari tata letak Anda. Sesuatu yang istimewa, sangat berbeda. Kode Anda kembali nulluntuk itemdan itu menyebabkan crash. Yang Anda butuhkan adalah melakukan:

MenuItem item = menu.findItem(R.id.addAction);

Berikut adalah urutan di mana Anda harus memanggil: panggilan pertama invalidateOptionsMenu()dan kemudian di dalam onCreateOptionsMenu(Menu)memperoleh referensi ke MenuItem (dengan memanggil menu.findItem()) dan panggilan setVisible()di atasnya


Ini adalah apa yang saya pikirkan pada awalnya, tetapi ini crash aplikasi.
Aduk Zoltán

3
@Stir Zoltán: Ya begitulah cara Anda melakukannya, Anda mungkin melakukan kesalahan jika aplikasi macet. Misalnya, Anda MenuItemmungkin nullkarena Anda menggunakan getItemalih-alih findItem. Kami tidak akan pernah tahu, tanpa melihat kode dan log kerusakan Anda.
K-ballo

OK tapi bagaimana saya bisa mendapatkan referensi ke menu di luar metode onCreateOptionsMenu?
Aduk Zoltán

7
@Stir Zoltán: Saya yakin Anda tidak masuk akal dengan komentar terakhir itu ... Cukup dapatkan referensi ke item menu Anda di onCreateOptionsMenu, dan atur visibilitas item pada saat itu. Atau simpan referensi di sekitar sampai Anda memutuskan apakah itu akan terlihat atau tidak.
K-ballo

33
Saya pikir (paling-paling) jawaban ini tidak ditulis dengan baik karena urutan langkahnya salah. Urutan yang benar adalah untuk panggilan pertama invalidateOptionsMenu()dan kemudian di dalam onCreateOptionsMenu(Menu)mendapatkan referensi ke MenuItem(dengan memanggil menu.findItem()) dan memanggilnya setVisible(). Jawaban oleh suhas_sm dan oleh P1r4nh4 menyajikan pendekatan yang benar.
Ted Hopp

163

Ditemukan tambahan untuk pertanyaan ini:

Jika Anda ingin mengubah visibilitas item menu Anda saat bepergian, Anda hanya perlu mengatur variabel anggota dalam aktivitas Anda untuk mengingat bahwa Anda ingin menyembunyikan menu dan memanggil invalidateOptionsMenu()dan menyembunyikan item dalam onCreateOptionsMenu(...)metode yang diganti .

//anywhere in your code
...
mState = HIDE_MENU; // setting state
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == HIDE_MENU)
    {
        for (int i = 0; i < menu.size(); i++)
            menu.getItem(i).setVisible(false);
    }
}

Dalam contoh saya, saya telah menyembunyikan semua item.


2
Inilah yang sebenarnya saya cari. memegang MenuItem dan memanggil setVisible () tampaknya tidak melakukan apa yang saya harapkan (mungkin karena saya memanggil invalidateOptionsMenu () sesudahnya, sehingga membangun kembali menu), tetapi bagaimanapun juga - ini bekerja persis seperti yang saya harapkan, terima kasih!
Mat

4
Jika Anda akan menyembunyikan setiap item, ada cara yang lebih mudah. Alih-alih mengulangi setiap item di sini, Anda bisa melakukan: if (HIDE_MENU) { return false; } else { getSupportMenuInflater().inflate(R.menu.menu_settings, menu); return true; }Status dokumen: "Anda harus mengembalikan true untuk menu yang akan ditampilkan; jika Anda mengembalikan false, itu tidak akan ditampilkan".
w3bshark

Juga, saya ingin menyebutkan bahwa pendekatan ini jauh lebih bersih daripada jawaban yang diterima. Terima kasih telah berbagi!
w3bshark

dengan memanggil invalidateOptionMenu () onCreateOptionMenu () dipanggil dan saya menangani kondisi saya di onCreateOptionMenu (). Terima kasih atas jawaban yang baik
user1912026

onPrepareOptionsMenu()harus digunakan untuk logika tampilkan / sembunyikan alih-alih onCreateOptionsMenu()karena hanya dipanggil satu kali sehingga tidak berguna jika Anda ingin mengubah item menu setelah inisialisasi. Jadi mengembang di onCreate, tetapi tampilkan / sembunyikan di onPrepare.
JCutting8

89

Iya.

  1. Anda dapat mengatur bendera / kondisi.
  2. Panggil invalidateOptionsMenu()ketika Anda ingin menyembunyikan opsi. Ini akan memanggil onCreateOptionsMenu().
  3. Di onCreateOptionsMenu(), periksa bendera / kondisi dan perlihatkan atau sembunyikan dengan cara berikut:
MenuItem item = menu.findItem(R.id.menu_Done);

if (flag/condition)) {
  item.setVisible(false); 
} else { }

2
Bukankah seharusnya invalidateOptionsMenubukan invalidateOptions?
razz

3
Jika Anda membuat bendera menjadi boolean, Anda dapat mengatur visibilitas item ke bendera (atau! Bendera) jika perlu. Jadi, item.setVisbility (! Flag); membuat ini satu liner tanpa syarat jika.
jwehrle

di mana variabel "menu" didefinisikan?
Jonathan

Ini diteruskan sebagai parameter keonCreateOptionsMenu
suhas_sm

menggunakan metode ini berarti item tersebut masih menghabiskan ruang dan Anda mungkin berakhir dengan "celah" di UI Anda di mana tombol seharusnya. Menggunakan removeItem di onPrepareOptionsMenu () akan melakukan trik.
JCutting8

39

Anda dapat memanggil ini:

MenuItem item = menu.findItem(R.id.my_item);
item.setVisible(false);

Memperbarui:

Pastikan kode Anda tidak kembali nulluntuk itematau mungkin kecelakaan aplikasi.


menggunakan metode ini berarti item tersebut masih menghabiskan ruang dan Anda mungkin berakhir dengan "celah" di UI Anda di mana tombol seharusnya. Menggunakan removeItem di onPrepareOptionsMenu () akan melakukan trik.
JCutting8

33

Saya mencari jawaban dengan konteks yang lebih sedikit. Sekarang saya sudah menemukan jawabannya, saya akan menambahkan jawaban itu.

Sembunyikan tombol secara default di menu xml

Secara default tombol share akan disembunyikan, seperti yang ditetapkan oleh android:visible="false".

masukkan deskripsi gambar di sini

main_menu.xml

<?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">

    <!-- hide share button by default -->
    <item
        android:id="@+id/menu_action_share"
        android:icon="@drawable/ic_share_white_24dp"
        android:visible="false"     
        android:title="Share"
        app:showAsAction="always"/>

    <item
        android:id="@+id/menu_action_settings"
        android:icon="@drawable/ic_settings_white_24dp"
        android:title="Setting"
        app:showAsAction="ifRoom"/>

</menu>

Tampilkan tombol dalam kode

Tetapi tombol share dapat ditampilkan berdasarkan kondisi tertentu.

masukkan deskripsi gambar di sini

MainActivity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem shareItem = menu.findItem(R.id.menu_action_share);

    // show the button when some condition is true
    if (someCondition) {        
        shareItem.setVisible(true);
    }

    return true;
}

Lihat juga


onPrepareOptionsMenu () harus digunakan untuk menampilkan / menyembunyikan logika alih-alih onCreateOptionsMenu () karena hanya dipanggil sekali sehingga tidak berguna jika Anda ingin mengubah item menu setelah inisialisasi. Jadi mengembang di onCreate, tetapi tampilkan / sembunyikan di onPrepare, lalu gunakan invalidateOptionsMenu()untuk menyegarkan menu.
JCutting8

24

tidak bekerja untuk saya. Saya harus secara eksplisit menggunakan onPrepareOptionsMenuuntuk mengatur item tidak terlihat.

Jadi gunakan onCreateOptionsMenuuntuk membuat menu dan onPrepareOptionsMenuuntuk mengubah visibilitas dll.


1
Bagi saya ini bekerja dua arah, tetapi berdasarkan dokumen Android onPrepareOptionsMenu sepertinya tempat yang tepat untuk melakukan jenis operasi ini: "Siapkan menu opsi standar Layar untuk ditampilkan. Ini disebut tepat sebelum menu ditampilkan, setiap kali ditampilkan Anda dapat menggunakan metode ini untuk mengaktifkan / menonaktifkan item secara efisien atau memodifikasi konten secara dinamis. "
yuval

Ya, ini ideal. onPrepareOptionsMenu () harus digunakan untuk menampilkan / menyembunyikan logika alih-alih onCreateOptionsMenu () karena hanya dipanggil sekali sehingga tidak berguna jika Anda ingin mengubah item menu setelah inisialisasi. Jadi mengembang di onCreate, tetapi tampilkan / sembunyikan di onPrepare, lalu gunakan invalidateOptionsMenu()untuk menyegarkan menu.
JCutting8

9

Awalnya atur visibilitas item menu ke false dalam file tata letak menu sebagai berikut:

<?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:visible="false"
        android:id="@+id/action_do_something"
        android:title="@string/txt_do_something"
        app:showAsAction="always|withText"
        android:icon="@drawable/ic_done"/>
</menu>

Anda kemudian dapat dengan mudah mengatur visibilitas item menu ke false di onCreateOptionsMenu () Anda setelah menggembungkan menu.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(menu,R.menu.menu);
    MenuItem item = menu.findItem(R.id.menuItemId);
    if (item != null){
        item.setVisible(false);
    }
}

onCreateOptionsMenu tidak mengembalikan nilai boolean. Solusinya bekerja dengan sempurna.
Joseph


7

Ini bekerja untuk saya dari Aktivitas dan Fragmen

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    if (menu.findItem(R.id.action_messages) != null)
        menu.findItem(R.id.action_messages).setVisible(false);
}

1
Dalam kasus saya onPrepareOptionsMenu mengembalikan boolean, bukan batal.
CoolMind

6

Jawaban P1r4nh4 berfungsi dengan baik, saya hanya menyederhanakannya menggunakan flag boolean:

public int mState = 0; //at the top of the code
//where you want to trigger the hide action
mState = 1; // to hide or mState = 0; to show
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == 1) //1 is true, 0 is false
    {
        //hide only option 2
            menu.getItem(2).setVisible(false);
    }
}

2
Menggunakan 0dan 1bukan "boolean flag", ini pseudo-boolean. selain itu, tidak ada alasan untuk menggunakan boolean yang sebenarnya di sini.
Ingo Bürk

2
Anda juga dapat memiliki beberapa status, bukan hanya satu untuk disembunyikan dan satu untuk ditampilkan. Bergantung pada kompleksitas aplikasi Anda dan penolakan Anda untuk menulis aktivitas baru untuk status aplikasi baru, Anda mungkin memiliki status SHOW_ALL, status HIDE_ALL, tetapi juga status HIDE_EDIT atau HIDE_SHARE jika Anda ingin menyembunyikan bagian tertentu dari menu Anda.
P1r4nh4

4

Menurut situs Resmi Pengembang Android, OnCreateOptionMenu (Menu menu) tidak direkomendasikan untuk mengubah item menu atau ikon, visibilitas..etc di Runtime.

Setelah sistem memanggil onCreateOptionsMenu (), ia mempertahankan instance Menu yang Anda isi dan tidak akan memanggil onCreateOptionsMenu () lagi kecuali jika menu tidak valid karena suatu alasan. Namun, Anda harus menggunakan onCreateOptionsMenu () hanya untuk membuat status menu awal dan tidak membuat perubahan selama siklus hidup aktivitas.

Jika Anda ingin memodifikasi menu opsi berdasarkan peristiwa yang terjadi selama siklus hidup aktivitas, Anda dapat melakukannya dalam metode onPrepareOptionsMenu (). Metode ini memberi Anda objek Menu seperti yang ada saat ini sehingga Anda dapat memodifikasinya, seperti menambah, menghapus, atau menonaktifkan item. (Fragmen juga menyediakan panggilan balik onPrepareOptionsMenu (). - Situs Resmi Android -

Seperti yang Disarankan Anda dapat menggunakan ini pada PilihanPilih yang Terpilih (item MenuItem) metode input untuk melacak input pengguna.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.edit) {
        Intent intent = new Intent(this, ExampleActivity.class);
        intent.putExtra(BUNDLE_KEY, mConnection);
        startActivityForResult(intent, PICK_CHANGE_REQUEST);
        return true;
    } else if (id == R.id.delete) {
        showDialog(this);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

Jika Anda perlu mengubah Item Menu saat Run, Anda dapat menggunakan onPrepareOptionsMenu (menu Menu) untuk mengubahnya

@Override
public boolean onPrepareOptionsMenu(Menu menu){

    if (Utils.checkNetworkStatus(ExampleActivity.this)) {
        menu.findItem(R.id.edit).setVisible(true);
        menu.findItem(R.id.delete).setVisible(true);
    }else {
        menu.findItem(R.id.edit).setVisible(false);
        menu.findItem(R.id.delete).setVisible(false);
    }
    return true;
} 

beberapa item selalu terlihat, jadi ketika saya setVisible(false)untuk item selalu terlihat, itu tidak hilang sampai saya klik pada tiga titik (Menu itu sendiri). Jika saya menggunakan invalidateOptionsMenu()di onPrepareOptionsMenuitem segera mereorganisasi sendiri, tetapi mereka kehilangan tindakan mereka (jika saya klik pada item apapun, itu tidak apa-apa).
Aliton Oliveira

3

setel nilai ke variabel dan panggil invalidateOptionsMenu ();

sebagai contoh

    selectedid=arg2;
            invalidateOptionsMenu();


 public boolean onPrepareOptionsMenu(Menu menu) {

    if(selectedid==1){
        menu.findItem(R.id.action_setting).setVisible(false);
        menu.findItem(R.id.action_s2).setVisible(false);
        menu.findItem(R.id.action_s3).setVisible(false);
    }
    else{
        if(selectedid==2){
            menu.findItem(R.id.action_search).setVisible(false);
            menu.findItem(R.id.action_s4).setVisible(false);
            menu.findItem(R.id.action_s5).setVisible(false);
        }
    }
    return super.onPrepareOptionsMenu(menu);
}

beberapa item selalu terlihat, jadi ketika saya setVisible(false)untuk item selalu terlihat, itu tidak hilang sampai saya klik pada tiga titik (Menu itu sendiri). Jika saya menggunakan invalidateOptionsMenu()di onPrepareOptionsMenuitem segera mereorganisasi sendiri, tetapi mereka kehilangan tindakan mereka (jika saya klik pada item apapun, itu tidak apa-apa).
Aliton Oliveira

3

Anda dapat menggunakannya toolbar.getMenu().clear();untuk menyembunyikan semua item menu sekaligus


@Ajeet_Yadav apakah ada cara untuk membuat menu terlihat setelah Anda menghapusnya?
Shawn

3

Dengan mengatur Visibilitas semua item dalam Menu, menu appbar atau menu overflow akan menjadi Sembunyikan secara otomatis

Contoh

private Menu menu_change_language;

...

...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    ...
    ...
    menu_change_language = menu;
    menu_change_language.findItem(R.id.menu_change_language)
           .setVisible(true);

    return super.onCreateOptionsMenu(menu);
}

Sebelum pergi ke bagian lain, gunakan kode di bawah ini:

if(menu_change_language != null){                 
    menu_change_language.findItem(R.id.menu_change_language)
       .setVisible(false);
}

2

https://stackoverflow.com/a/21215280/466363 - dijawab oleh Look Alterno dan Sufian

  • ActivityCompat.invalidateOptionsMenu () tidak memanggil balik onPrepareOptionsMenu (); itu hanya memperbarui menu secara langsung.
  • SomeMethod () saya dipanggil dari beberapa tempat, bahkan sebelum onCreateOptionsMenu (), jadi saya harus memeriksa mMenu! = Null.
  • harus bekerja menggunakan API 8

.

private Menu mMenu;
   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
       inflater.inflate(R.menu.track_fragment, menu);
       mMenu = menu;
       }
   ...
   private void someMethod() {
   ...
       if (mMenu != null) {
          MenuItem item = mMenu.findItem(R.id.new_track);
          if (item != null) {
               item.setVisible(false);
               ActivityCompat.invalidateOptionsMenu(this.getActivity());
           }
       }
   ...
   }
  • ActivityCompat.invalidateOptionsMenu () tidak memanggil balik onPrepareOptionsMenu (); itu hanya memperbarui menu secara langsung.

  • SomeMethod () saya dipanggil dari beberapa tempat, bahkan sebelum onCreateOptionsMenu (), jadi saya harus memeriksa mMenu! = Null.

  • harus bekerja menggunakan API 8

2

Jika Anda melakukan semuanya seperti pada jawaban di atas, tetapi item menu masih terlihat, periksa apakah Anda merujuk ke sumber daya yang unik . Misalnya, di onCreateOptionsMenu atau onPrepareOptionsMenu

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    MenuItem menuOpen = menu.findItem(R.id.menu_open);
    menuOpen.setVisible(false);
}

Ctrl + Klik R.id.menu_open dan periksa bahwa itu ada hanya dalam satu file menu. Jika sumber ini sudah digunakan di mana saja dan dimuat dalam suatu kegiatan, ia akan mencoba bersembunyi di sana.


2

Cara terbaik untuk menyembunyikan semua item dalam menu hanya dengan satu perintah adalah menggunakan "grup" pada xml menu Anda. Cukup tambahkan semua item menu yang akan ada di menu overflow Anda di dalam grup yang sama.

Dalam contoh ini kami memiliki dua item menu yang akan selalu ditampilkan (item reguler dan pencarian) dan tiga item melimpah:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/someItemNotToHide1"
        android:title="ITEM"
        app:showAsAction="always" />

    <item
        android:id="@+id/someItemNotToHide2"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:title="Search"/>

    <group android:id="@+id/overFlowItemsToHide">
    <item android:id="@+id/someID" 
    android:orderInCategory="1" app:showAsAction="never" />
    <item android:id="@+id/someID2" 
    android:orderInCategory="1" app:showAsAction="never" />
    <item android:id="@+id/someID3" 
    android:orderInCategory="1" app:showAsAction="never" />
    </group>
</menu>

Kemudian, pada aktivitas Anda (lebih disukai di onCreateOptionsMenu), gunakan perintah setGroupVisible untuk mengatur semua visibilitas item menu menjadi false atau true.

public boolean onCreateOptionsMenu(Menu menu) {
   menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}

Jika Anda ingin menggunakan perintah ini di tempat lain di aktivitas Anda, pastikan untuk menyimpan kelas menu ke lokal, dan selalu periksa apakah menu nol, karena Anda dapat mengeksekusi sebelum createOptionsMenu:

Menu menu;

public boolean onCreateOptionsMenu(Menu menu) {
       this.menu = menu;

}

public void hideMenus() {
       if (menu != null) menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible       
}


1

Saya pikir pendekatan yang lebih baik adalah dengan menggunakan variabel anggota untuk menu, menginisialisasi di onCreateOptionsMenu () dan hanya menggunakan setVisible () sesudahnya, tanpa membatalkan pilihan menu.


1

kode ini bekerja untuk saya

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu,menu);
    if (Application.sharedPreferences.getInt("type",1) == 2)
    {
        menuItem = menu.findItem(R.id.menu_travel_orders);
        menuItem.setVisible(false);
    }
    return super.onCreateOptionsMenu(menu);
}

1

Pendekatan ini bekerja untuk saya:

private  Menu thismenu;

if (condition)
{
   if(thismenu != null)
   {
       thismenu.findItem(R.id.menu_save).setVisible(true);
       Toast.makeText(ProfileActivity.this, 
    ""+thismenu.findItem(R.id.menu_save).getTitle(),
                Toast.LENGTH_SHORT).show();
   }else
   {
       thismenu.findItem(R.id.menu_save).setVisible(false);
   }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   getMenuInflater().inflate(R.menu.profile_menu, menu);
   thismenu = menu;

   return true;
}

1

Anda mencoba mengakses item menu dari suatu aktivitas, yang tidak memiliki akses ke cakupan. Panggilan untuk menemukan item menu akan kembali nol , karena tampilan tidak terikat dengan aktivitas maupun tata letak tempat Anda menelepon.

Item menu diikat dengan item seperti " Bar Navigasi " yang pada gilirannya diikat dengan aktivitas yang sesuai.

Jadi inisialisasi pandangan-pandangan tersebut dalam aktivitas (), dan kemudian mengakses item menu yang menyertai tampilan itu.

Navigation navView;
navView = findViewById(R.id.navigationView);

MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.setVisible(false);

1

menggunakan invalidateOptionsMenu()

untuk menelepon onPrepareOptionsMenu(menu: Menu?)

Anda harus menggunakan onCreateOptionsMenu () hanya untuk membuat status menu awal dan tidak membuat perubahan selama siklus hidup aktivitas ...

Ketika suatu peristiwa terjadi dan Anda ingin melakukan pembaruan menu, Anda harus memanggil invalidateOptionsMenu () untuk meminta panggilan sistem padaPrepareOptionsMenu ().

https://developer.android.com/guide/topics/ui/menus


0

Android kotlin, sembunyikan atau atur visibilitas item menu di panel tindakan secara terprogram.

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater = menuInflater
    inflater.inflate(R.menu.main_menu, menu)
    val method = menu.findItem(R.id.menu_method)
    method.isVisible = false //if want to show set true
    return super.onCreateOptionsMenu(menu)
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.