Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Menu

Menu adalah komponen antarmuka pengguna yang lazim dalam banyak tipe aplikasi. Untuk menyediakan pengalaman pengguna yang sudah umum dan konsisten, Anda harus menggunakan API Menu untuk menyajikan tindakan dan opsi lain kepada pengguna dalam aktivitas.

Mulai dengan Android 3.0 (API level 11), perangkat Android tidak perlu lagi menyediakan tombol Menu tersendiri. Dengan perubahan ini, aplikasi Android harus bermigrasi dari dependensi pada panel menu 6 item biasa, dan sebagai gantinya menyediakan panel aplikasi untuk menyajikan berbagai tindakan pengguna yang lazim.

Walaupun desain dan pengalaman pengguna untuk sebagian item menu telah berubah, semantik untuk mendefinisikan serangkaian tindakan dan opsi masih berdasarkan pada API Menu. Panduan ini menampilkan cara membuat tiga tipe dasar penyajian menu atau aksi pada semua versi Android:

Menu opsi dan panel aplikasi
Menu opsi adalah kumpulan item menu utama untuk suatu aktivitas. Di sinilah Anda harus menempatkan tindakan yang memiliki dampak global pada aplikasi, seperti "Penelusuran", "Tulis email", dan "Setelan".

Lihat bagian tentang Membuat Menu Opsi.

Menu konteks dan mode tindakan kontekstual
Menu konteks adalah menu mengambang yang muncul saat pengguna mengklik lama pada suatu elemen. Menu ini menyediakan tindakan yang memengaruhi materi atau bingkai konteks yang dipilih.

Mode tindakan kontekstual menampilkan item aksi yang memengaruhi materi yang dipilih dalam panel di bagian atas layar dan memungkinkan pengguna memilih beberapa item sekaligus.

Lihat bagian tentang Membuat Menu Kontekstual.

Menu pop-up
Menu pop-up menampilkan daftar item secara vertikal yang dipasang pada tampilan yang memanggil menu. Ini cocok untuk menyediakan aksi selebihnya yang terkait dengan konten tertentu atau untuk menyediakan opsi bagi bagian kedua dari suatu perintah. Tindakan di menu pop-up tidak boleh langsung memengaruhi konten yang bersangkutan, karena itu adalah fungsi tindakan kontekstual. Sebaliknya, menu pop-up adalah untuk tindakan tambahan yang terkait dengan region materi dalam aktivitas Anda.

Lihat bagian tentang Membuat Menu Pop-up.

Mendefinisikan Menu dalam XML

Untuk semua tipe menu, Android menyediakan format XML standar untuk mendefinisikan item menu. Sebagai ganti membuat menu di kode aktivitas, Anda harus mendefinisikan menu dan semua item menunya dalam resource menu XML. Anda kemudian dapat meng-inflate resource menu (memuatnya sebagai objek Menu) dalam aktivitas atau fragmen.

Menggunakan resource menu adalah praktik yang baik karena beberapa alasan:

  • Memvisualisasikan struktur menu dalam XML menjadi lebih mudah.
  • Cara ini memisahkan materi untuk menu dari kode perilaku aplikasi Anda.
  • Cara ini memungkinkan Anda membuat konfigurasi menu alternatif untuk berbagai versi platform, ukuran layar, dan konfigurasi lainnya dengan memanfaatkan framework resource aplikasi.

Untuk mendefinisikan menu, buatlah sebuah file XML dalam direktori res/menu/ project dan buat menu dengan elemen-elemen berikut:

<menu>
Mendefinisikan Menu, yang merupakan sebuah container item menu. Elemen <menu> harus menjadi node root untuk file dan dapat menampung satu atau beberapa elemen <item> dan <group>.
<item>
Membuat MenuItem, yang mewakili satu item menu. Elemen ini dapat berisi elemen <menu> bersarang untuk membuat submenu.
<group>
Container opsional yang tak terlihat untuk elemen-elemen <item>. Container ini memungkinkan Anda mengelompokkan item menu agar bisa berbagi properti seperti status aktif dan visibilitas. Untuk informasi selengkapnya, lihat bagian tentang Membuat Grup Menu.

Berikut ini adalah contoh menu bernama game_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          android:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

Elemen <item> mendukung beberapa atribut yang dapat Anda gunakan untuk mendefinisikan penampilan dan perilaku item. Item menu di atas mencakup atribut berikut:

android:id
ID resource unik bagi item, yang memungkinkan aplikasi mengenali item saat pengguna memilihnya.
android:icon
Acuan ke drawable untuk digunakan sebagai ikon item.
android:title
Acuan ke string untuk digunakan sebagai judul item.
android:showAsAction
Menetapkan waktu dan cara item ini muncul sebagai item aksi di panel aplikasi.

Ini adalah atribut-atribut terpenting yang harus Anda gunakan, tetapi banyak lagi yang tersedia. Untuk informasi tentang semua atribut yang didukung, lihat dokumen Resource Menu.

Anda dapat menambahkan submenu ke sebuah item di menu apa saja dengan menambahkan elemen <menu> sebagai turunan <item>. Submenu berguna saat aplikasi Anda memiliki banyak fungsi yang dapat ditata ke dalam topik-topik, seperti item dalam sebuah panel menu aplikasi PC (File, Edit, Lihat, dsb.). Contoh:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>

Untuk menggunakan menu dalam aktivitas, Anda harus meng-inflate resource menu (mengonversi resource XML menjadi objek yang dapat diprogram) menggunakan MenuInflater.inflate(). Di bagian berikut, Anda akan melihat cara meng-inflate menu untuk tiap tipe menu.

Membuat Menu Opsi

Gambar 1. Menu opsi di Browser.

Menu opsi adalah tempat Anda harus menyertakan tindakan dan opsi lain yang relevan dengan konteks aktivitas saat ini, seperti "Telusuri", "Tulis email", dan "Setelan".

Tempat item dalam menu opsi muncul di layar bergantung pada versi aplikasi yang Anda kembangkan:

  • Jika Anda telah mengembangkan aplikasi untuk Android 2.3.x (API level 10) atau yang lebih lama, konten menu opsi muncul di bagian atas layar saat pengguna menekan tombol Menu, seperti yang ditunjukkan pada gambar 1. Bila dibuka, bagian yang terlihat pertama adalah menu ikon, yang menampung hingga enam item menu. Jika menu Anda menyertakan lebih dari enam item, Android akan meletakkan item keenam dan sisanya ke dalam menu tambahan, yang dapat dibuka pengguna dengan memilih Lainnya.
  • Jika Anda mengembangkan aplikasi untuk Android 3.0 (API level 11) dan yang lebih baru, item menu opsi tersedia dalam panel aplikasi. Secara default, sistem meletakkan semua item dalam aksi selebihnya, yang dapat ditampilkan pengguna dengan ikon aksi selebihnya di sisi kanan panel aplikasi (atau dengan menekan tombol Menu, jika tersedia). Untuk mengaktifkan akses cepat ke tindakan penting, Anda dapat mempromosikan beberapa item agar muncul pada panel aplikasi dengan menambahkan android:showAsAction="ifRoom" ke elemen-elemen <item> yang bersangkutan (lihat gambar 2).

    Untuk informasi selengkapnya tentang perilaku item aksi dan perilaku panel aplikasi lainnya, lihat kelas pelatihan Menambahkan Panel Aplikasi.

Gambar 2. Aplikasi Google Spreadsheet, menampilkan beberapa tombol, termasuk tombol aksi selebihnya.

Anda dapat mendeklarasikan item untuk menu opsi dari subclass Activity atau subclass Fragment. Jika aktivitas maupun fragmen Anda mendeklarasikan item menu opsi, keduanya akan dikombinasikan dalam UI. Item aktivitas akan muncul terlebih dahulu, diikuti oleh item setiap fragmen sesuai dengan urutan penambahan setiap fragmen ke aktivitas. Jika perlu, Anda dapat menyusun ulang item menu dengan atribut android:orderInCategory dalam setiap <item> yang perlu Anda pindahkan.

Untuk menetapkan menu opsi suatu aktivitas, ganti onCreateOptionsMenu() (fragmen-fragmen menyediakan callback onCreateOptionsMenu() sendiri). Dalam metode ini, Anda dapat meng-inflate resource menu (yang didefinisikan dalam XML) menjadi Menu yang disediakan dalam callback. Contoh:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater: MenuInflater = menuInflater
    inflater.inflate(R.menu.game_menu, menu)
    return true
}

Java

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

Anda juga dapat menambahkan item menu menggunakan add() dan mengambil item dengan findItem() untuk merevisi propertinya dengan API MenuItem.

Jika Anda mengembangkan aplikasi untuk Android 2.3.x dan yang lebih lama, sistem akan memanggil onCreateOptionsMenu() untuk membuat menu opsi saat pengguna membuka menu untuk pertama kali. Jika Anda mengembangkan aplikasi untuk Android 3.0 dan yang lebih baru, sistem akan memanggil onCreateOptionsMenu() saat memulai aktivitas, untuk menampilkan item menu pada panel aplikasi.

Menangani peristiwa klik

Bila pengguna memilih item dari menu opsi (termasuk item aksi dalam panel aplikasi), sistem akan memanggil metode onOptionsItemSelected() aktivitas Anda. Metode ini meneruskan MenuItem yang dipilih. Anda dapat mengidentifikasi item dengan memanggil getItemId(), yang mengembalikan ID unik untuk item menu itu (yang didefinisikan oleh atribut android:id dalam resource menu atau dengan integer yang diberikan ke metode add()). Anda dapat mencocokkan ID ini dengan item menu yang diketahui untuk melakukan tindakan yang sesuai. Contoh:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle item selection
    return when (item.itemId) {
        R.id.new_game -> {
            newGame()
            true
        }
        R.id.help -> {
            showHelp()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.new_game:
            newGame();
            return true;
        case R.id.help:
            showHelp();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Bila Anda berhasil menangani sebuah item menu, kembalikan true. Jika tidak menangani item menu, Anda harus memanggil implementasi superclass onOptionsItemSelected() (implementasi default mengembalikan false).

Jika aktivitas Anda menyertakan fragmen, sistem akan memanggil lebih dahulu onOptionsItemSelected() untuk aktivitas tersebut, kemudian untuk setiap fragmen (sesuai dengan urutan penambahan fragmen) hingga satu fragmen mengembalikan true atau semua fragmen telah dipanggil.

Tips: Android 3.0 menambahkan kemampuan bagi Anda untuk menentukan perilaku saat diklik untuk item menu di XML, menggunakan atribut android:onClick. Nilai atribut harus berupa nama metode yang didefinisikan aktivitas dengan menggunakan menu. Metode harus bersifat publik dan menerima satu parameter MenuItem bila sistem memanggilnya, metode ini akan meneruskan item menu yang dipilih. Untuk informasi selengkapnya dan contoh, lihat dokumen Resource Menu.

Tips: Jika aplikasi Anda berisi beberapa aktivitas dan beberapa di antaranya menyediakan menu opsi yang sama, pertimbangkan untuk membuat aktivitas yang tidak menerapkan apa pun kecuali metode onCreateOptionsMenu() dan onOptionsItemSelected(). Kemudian perluas class ini untuk setiap aktivitas yang harus menggunakan menu opsi yang sama. Dengan cara ini Anda dapat mengelola satu set kode untuk menangani tindakan menu dan setiap class turunan mewarisi perilaku menu tersebut. Jika Anda ingin menambahkan item menu ke salah satu aktivitas turunan, ganti onCreateOptionsMenu() di aktivitas tersebut. Panggil super.onCreateOptionsMenu(menu) agar item menu asli dibuat, kemudian tambahkan item menu yang baru dengan menu.add(). Anda juga dapat mengganti perilaku superclass untuk setiap item menu.

Mengubah item menu saat waktu proses

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

Jika Anda ingin mengubah menu opsi berdasarkan peristiwa yang terjadi selama siklus proses aktivitas, Anda dapat melakukannya dalam metode onPrepareOptionsMenu(). Metode ini meneruskan objek Menu sebagaimana adanya saat ini sehingga Anda dapat mengubahnya, seperti menambah, membuang, atau menonaktifkan item. (Fragmen juga menyediakan callback onPrepareOptionsMenu().)

Pada Android 2.3.x dan yang lebih lama, sistem akan memanggil onPrepareOptionsMenu() setiap kali pengguna membuka menu opsi (menekan tombol Menu ).

Pada Android 3.0 dan yang lebih baru, menu opsi dianggap sebagai selalu terbuka saat item menu ditampilkan pada panel aplikasi. Bila ada peristiwa dan Anda ingin melakukan pembaruan menu, Anda harus memanggil invalidateOptionsMenu() untuk meminta sistem memanggil onPrepareOptionsMenu().

Note: Anda tidak boleh mengubah item dalam menu opsi berdasarkan View yang saat ini difokus. Saat dalam mode sentuh (bila pengguna tidak sedang menggunakan trackball atau d-pad), tampilan tidak dapat mengambil fokus, sehingga Anda tidak boleh menggunakan fokus sebagai dasar untuk mengubah item dalam menu opsi. Jika Anda ingin menyediakan item menu yang sesuai konteks pada View, gunakan Menu Konteks.

Membuat Menu Kontekstual

Gambar 3. Cuplikan layar menu konteks mengambang (kiri) dan panel tindakan kontekstual (kanan).

Menu kontekstual menawarkan tindakan yang memengaruhi item atau bingkai konteks tertentu dalam UI. Anda dapat menyediakan menu konteks untuk tampilan apa saja, tetapi menu ini paling sering digunakan untuk item dalam ListView, GridView, atau kumpulan tampilan lainnya yang dapat digunakan pengguna untuk melakukan tindakan langsung pada setiap item.

Ada dua cara menyediakan tindakan kontekstual:

  • Dalam menu konteks mengambang. Menu muncul sebagai daftar item menu mengambang (serupa dengan dialog) bila pengguna mengklik lama (menekan dan menahan) pada tampilan yang mendeklarasikan dukungan bagi menu konteks. Pengguna dapat melakukan tindakan kontekstual pada satu item untuk setiap kalinya.
  • Dalam mode tindakan kontekstual. Mode ini adalah implementasi sistem ActionMode yang menampilkan panel tindakan kontekstual di bagian atas layar dengan item aksi yang memengaruhi item yang dipilih. Bila mode ini aktif, pengguna dapat melakukan aksi pada beberapa item sekaligus (jika aplikasi Anda mengizinkannya).

Catatan: Mode tindakan kontekstual tersedia di Android 3.0 (API level 11) dan yang lebih baru dan merupakan teknik yang lebih disukai untuk menampilkan tindakan kontekstual jika tersedia. Jika aplikasi Anda mendukung versi yang lebih lama daripada 3.0, maka Anda harus mundur ke menu konteks mengambang pada perangkat-perangkat tersebut.

Membuat menu konteks mengambang

Untuk menyediakan menu konteks mengambang:

  1. Daftarkan View yang akan diatribusikan dengan menu konteks dengan memanggil registerForContextMenu() dan meneruskan View untuknya.

    Jika aktivitas Anda menggunakan ListView atau GridView dan Anda ingin setiap item untuk menyediakan menu konteks yang sama, daftarkan semua item ke menu konteks dengan meneruskan ListView atau GridView ke registerForContextMenu().

  2. Implementasikan metode onCreateContextMenu() dalam Activity atau Fragment.

    Bila tampilan yang terdaftar menerima peristiwa klik-lama, sistem akan memanggil metode onCreateContextMenu() Anda. Inilah tempat Anda mendefinisikan item menu, biasanya dengan meng-inflate resource menu. Contoh:

    Kotlin

    override fun onCreateContextMenu(menu: ContextMenu, v: View,
                            menuInfo: ContextMenu.ContextMenuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo)
        val inflater: MenuInflater = menuInflater
        inflater.inflate(R.menu.context_menu, menu)
    }
    

    Java

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
    }
    

    MenuInflater memungkinkan Anda untuk meng-inflate menu konteks resource menu. Parameter metode callback menyertakan View yang dipilih pengguna dan objek ContextMenu.ContextMenuInfo yang menyediakan informasi tambahan tentang item yang dipilih. Jika aktivitas Anda memiliki beberapa tampilan yang masing-masingnya menyediakan menu konteks berbeda, Anda dapat menggunakan parameter ini untuk menentukan menu konteks yang harus di-inflate.

  3. Implementasikan onContextItemSelected().

    Bila pengguna memilih item menu, sistem akan memanggil metode ini sehingga Anda dapat melakukan aksi yang sesuai. Contoh:

    Kotlin

    override fun onContextItemSelected(item: MenuItem): Boolean {
        val info = item.menuInfo as AdapterView.AdapterContextMenuInfo
        return when (item.itemId) {
            R.id.edit -> {
                editNote(info.id)
                true
            }
            R.id.delete -> {
                deleteNote(info.id)
                true
            }
            else -> super.onContextItemSelected(item)
        }
    }
    

    Java

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
            case R.id.edit:
                editNote(info.id);
                return true;
            case R.id.delete:
                deleteNote(info.id);
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }
    

    Metode getItemId() melakukan kueri ID untuk item menu yang dipilih, yang harus Anda tetapkan ke setiap item menu dalam XML dengan menggunakan atribut android:id, seperti yang ditampilkan di bagian tentang Mendefinisikan Menu dalam XML.

    Bila Anda berhasil menangani sebuah item menu, kembalikan true. Jika tidak menangani item menu, Anda harus meneruskan item menu ke implementasi superclass. Jika aktivitas Anda menyertakan fragmen, aktivitas akan menerima callback ini lebih dahulu. Dengan memanggil superclass bila tidak ditangani, sistem meneruskan peristiwa ke metode callback di setiap fragmen, satu per satu (sesuai dengan urutan penambahan fragmen) hingga true atau false dikembalikan. (Implementasi default untuk Activity dan android.app.Fragment mengembalikan false, sehingga Anda harus selalu memanggil superkelas bila tidak ditangani.)

Menggunakan mode tindakan kontekstual

Mode tindakan kontekstual adalah implementasi sistem ActionMode yang memfokuskan interaksi pengguna pada upaya melakukan aksi kontekstual. Bila seorang pengguna mengaktifkan mode ini dengan memilih item, a panel tindakan kontekstual akan muncul di bagian atas layar untuk menampilkan tindakan yang dapat dilakukan pengguna pada item yang dipilih saat ini. Selagi mode ini diaktifkan, pengguna dapat memilih beberapa item (jika Anda mengizinkan), membatalkan pilihan item, dan melanjutkan penelusuran dalam aktivitas (sebanyak yang ingin Anda izinkan). Mode tindakan dinonaktifkan dan panel tindakan kontekstual menghilang bila pengguna membatalkan pilihan semua item, menekan tombol BACK, atau memilih tindakan Done di sisi kiri panel tindakan.

Catatan: Panel tindakan kontekstual tidak harus diatribusikan dengan panel aplikasi. Keduanya beroperasi secara independen, walaupun panel tindakan kontekstual secara visual mengambil alih posisi panel aplikasi.

Untuk tampilan yang menyediakan tindakan kontekstual, Anda biasanya harus memanggil mode tindakan kontekstual pada salah satu dari dua peristiwa (atau keduanya):

  • Pengguna mengklik-lama pada tampilan.
  • Pengguna memilih kotak centang atau komponen UI yang serupa dalam tampilan.

Cara aplikasi memanggil mode tindakan kontekstual dan mendefinisikan perilaku setiap aksi bergantung pada desain Anda. Pada dasarnya ada dua desain:

  • Untuk tindakan kontekstual pada tampilan arbitrer dan tak didukung.
  • Untuk aksi kontekstual batch atas kelompok item dalam ListView atau GridView (memungkinkan pengguna memilih beberapa item dan melakukan aksi pada semua item itu).

Bagian berikut ini menjelaskan penyiapan yang diperlukan untuk setiap skenario.

Mengaktifkan mode tindakan kontekstual untuk tampilan individual

Jika Anda ingin memanggil mode tindakan kontekstual hanya bila pengguna memilih tampilan tertentu, Anda harus:

  1. Mengimplementasikan antarmuka ActionMode.Callback. Dalam metode callback-nya, Anda dapat menetapkan tindakan untuk panel tindakan kontekstual, merespons peristiwa klik pada item aksi, dan menangani peristiwa siklus proses lainnya untuk mode tindakan itu.
  2. Memanggil startActionMode() bila Anda ingin menampilkan panel (seperti saat pengguna mengklik-lama pada tampilan).

Contoh:

  1. Mengimplementasikan antarmuka ActionMode.Callback:

    Kotlin

    private val actionModeCallback = object : ActionMode.Callback {
        // Called when the action mode is created; startActionMode() was called
        override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
            // Inflate a menu resource providing context menu items
            val inflater: MenuInflater = mode.menuInflater
            inflater.inflate(R.menu.context_menu, menu)
            return true
        }
    
        // Called each time the action mode is shown. Always called after onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
            return false // Return false if nothing is done
        }
    
        // Called when the user selects a contextual menu item
        override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
            return when (item.itemId) {
                R.id.menu_share -> {
                    shareCurrentItem()
                    mode.finish() // Action picked, so close the CAB
                    true
                }
                else -> false
            }
        }
    
        // Called when the user exits the action mode
        override fun onDestroyActionMode(mode: ActionMode) {
            actionMode = null
        }
    }
    

    Java

    private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
    
        // Called when the action mode is created; startActionMode() was called
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Inflate a menu resource providing context menu items
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context_menu, menu);
            return true;
        }
    
        // Called each time the action mode is shown. Always called after onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false; // Return false if nothing is done
        }
    
        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.menu_share:
                    shareCurrentItem();
                    mode.finish(); // Action picked, so close the CAB
                    return true;
                default:
                    return false;
            }
        }
    
        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            actionMode = null;
        }
    };
    

    Perhatikan bahwa peristiwa callback ini hampir persis sama dengan callback untuk menu opsi, hanya saja setiap callback ini juga meneruskan objek ActionMode yang diatribusikan dengan peristiwa tersebut. Anda dapat menggunakan ActionMode API untuk membuat berbagai perubahan pada CAB, seperti merevisi judul dan subjudul dengan setTitle() dan setSubtitle() (berguna untuk menunjukkan jumlah item yang dipilih).

    Juga perhatikan kumpulan contoh di atas menyetel variabel mActionMode ke null bila mode tindakan dimusnahkan. Dalam langkah berikutnya, Anda akan melihat cara variabel diinisialisasi dan kegunaan menyimpan variabel anggota dalam aktivitas atau fragmen.

  2. Panggil startActionMode() untuk mengaktifkan mode tindakan kontekstual bila sesuai, seperti saat merespons klik-lama pada View:

    Kotlin

    someView.setOnLongClickListener { view ->
        // Called when the user long-clicks on someView
        when (actionMode) {
            null -> {
                // Start the CAB using the ActionMode.Callback defined above
                actionMode = activity?.startActionMode(actionModeCallback)
                view.isSelected = true
                true
            }
            else -> false
        }
    }
    

    Java

    someView.setOnLongClickListener(new View.OnLongClickListener() {
        // Called when the user long-clicks on someView
        public boolean onLongClick(View view) {
            if (actionMode != null) {
                return false;
            }
    
            // Start the CAB using the ActionMode.Callback defined above
            actionMode = getActivity().startActionMode(actionModeCallback);
            view.setSelected(true);
            return true;
        }
    });
    

    Bila Anda memanggil startActionMode(), sistem akan mengembalikan ActionMode yang dibuat. Dengan menyimpannya dalam variabel anggota, Anda dapat membuat perubahan ke panel tindakan kontekstual sebagai respons terhadap peristiwa lainnya. Dalam contoh di atas, ActionMode digunakan untuk memastikan bahwa instance ActionMode tidak dibuat kembali jika sudah aktif, dengan memeriksa apakah anggota bernilai null sebelum memulai mode tindakan.

Mengaktifkan tindakan kontekstual batch dalam ListView atau GridView

Jika Anda memiliki sekumpulan item dalam ListView atau GridView (atau ekstensi AbsListView lainnya) dan ingin memungkinkan pengguna melakukan tindakan batch, Anda harus:

Contoh:

Kotlin

val listView: ListView = getListView()
with(listView) {
    choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL
    setMultiChoiceModeListener(object : AbsListView.MultiChoiceModeListener {
        override fun onItemCheckedStateChanged(mode: ActionMode, position: Int,
                                               id: Long, checked: Boolean) {
            // Here you can do something when items are selected/de-selected,
            // such as update the title in the CAB
        }

        override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
            // Respond to clicks on the actions in the CAB
            return when (item.itemId) {
                R.id.menu_delete -> {
                    deleteSelectedItems()
                    mode.finish() // Action picked, so close the CAB
                    true
                }
                else -> false
            }
        }

        override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
            // Inflate the menu for the CAB
            val menuInflater: MenuInflater = mode.menuInflater
            menuInflater.inflate(R.menu.context, menu)
            return true
        }

        override fun onDestroyActionMode(mode: ActionMode) {
            // Here you can make any necessary updates to the activity when
            // the CAB is removed. By default, selected items are deselected/unchecked.
        }

        override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
            // Here you can perform updates to the CAB due to
            // an <code><a href="/reference/android/view/ActionMode.html#invalidate()">invalidate()</a></code> request
            return false
        }
    })
}

Java

ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position,
                                          long id, boolean checked) {
        // Here you can do something when items are selected/de-selected,
        // such as update the title in the CAB
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        // Respond to clicks on the actions in the CAB
        switch (item.getItemId()) {
            case R.id.menu_delete:
                deleteSelectedItems();
                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Inflate the menu for the CAB
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.context, menu);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        // Here you can make any necessary updates to the activity when
        // the CAB is removed. By default, selected items are deselected/unchecked.
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        // Here you can perform updates to the CAB due to
        // an <code><a href="/reference/android/view/ActionMode.html#invalidate()">invalidate()</a></code> request
        return false;
    }
});

Selesai. Kini bila pengguna memilih item dengan klik-lama, sistem akan memanggil metode onCreateActionMode() dan menampilkan panel tindakan kontekstual bersama tindakan yang ditetapkan. Saat panel tindakan kontekstual terlihat, pengguna dapat memilih item tambahan.

Dalam beberapa kasus di mana tindakan kontekstual menyediakan item aksi umum, Anda mungkin ingin menambahkan kotak centang atau elemen UI serupa yang memungkinkan pengguna memilih item, karena pengguna mungkin tidak menemukan perilaku klik-lama. Bila pengguna memilih kotak centang itu, Anda dapat memanggil mode tindakan kontekstual dengan menyetel item daftar yang bersangkutan ke status diberi tanda centang dengan setItemChecked().

Membuat Menu Pop-up

Gambar 4. Menu pop-up dalam aplikasi Gmail, dikaitkan pada tombol kelebihan di sudut kanan atas.

PopupMenu adalah menu modal yang dikaitkan ke View. Munculnya di bawah tampilan jangkar jika ada ruang, atau di atas tampilan jika tidak ada. Menu ini berguna untuk:

  • Menyediakan menu bergaya kelebihan (overflow) untuk tindakan yang berkaitan dengan materi tertentu (seperti header email Gmail, yang ditampilkan dalam gambar 4).

    Catatan: Ini tidak sama dengan menu konteks, yang umumnya untuk tindakan yang memengaruhi konten yang dipilih. Untuk tindakan yang memengaruhi materi yang dipilih, gunakan mode tindakan kontekstual atau menu konteks mengambang.

  • Memberikan bagian kedua dari kalimat perintah (seperti tombol bertanda "Tambah" yang menghasilkan menu pop-up dengan opsi "Tambah" yang berbeda).
  • Menyediakan daftar drop-down serupa dengan Spinner yang tidak mempertahankan pilihan persisten.

Catatan: PopupMenu tersedia dengan API level 11 dan yang lebih baru

Jika Anda mendefinisikan menu dalam XML, berikut ini adalah cara Anda menampilkan menu pop-up:

  1. Buat instance PopupMenu bersama konstruktornya, yang mengambil Context dan View aplikasi saat ini yang akan menjadi tempat mengaitkan menu.
  2. Gunakan MenuInflater untuk meng-inflate resource menu Anda ke dalam objek Menu yang dikembalikan oleh PopupMenu.getMenu().
  3. Panggil PopupMenu.show().

Misalnya, berikut ini adalah tombol dengan atribut android:onClick yang menampilkan menu pop-up:

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_overflow_holo_dark"
    android:contentDescription="@string/descr_overflow_button"
    android:onClick="showPopup" />

Aktivitas nanti dapat menampilkan menu pop-up seperti ini:

Kotlin

fun showPopup(v: View) {
    val popup = PopupMenu(this, v)
    val inflater: MenuInflater = popup.menuInflater
    inflater.inflate(R.menu.actions, popup.menu)
    popup.show()
}

Java

public void showPopup(View v) {
    PopupMenu popup = new PopupMenu(this, v);
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.actions, popup.getMenu());
    popup.show();
}

Dalam API level 14 dan yang lebih baru, Anda dapat mengombinasikan dua baris yang meng-inflate menu dengan PopupMenu.inflate().

Menu akan ditutup bila pengguna memilih item atau menyentuh di luar area menu. Anda dapat memproses peristiwa tutup dengan menggunakan PopupMenu.OnDismissListener.

Menangani peristiwa klik

Untuk melakukan suatu tindakan bila pengguna memilih item menu, Anda harus mengimplementasikan antarmuka PopupMenu.OnMenuItemClickListener dan mendaftarkannya pada PopupMenu dengan memanggil setOnMenuItemclickListener(). Bila pengguna memilih item, sistem akan memanggil callback onMenuItemClick() dalam antarmuka Anda.

Contoh:

Kotlin

fun showMenu(v: View) {
    PopupMenu(this, v).apply {
        // MainActivity implements OnMenuItemClickListener
        setOnMenuItemClickListener(this@MainActivity)
        inflate(R.menu.actions)
        show()
    }
}

override fun onMenuItemClick(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.archive -> {
            archive(item)
            true
        }
        R.id.delete -> {
            delete(item)
            true
        }
        else -> false
    }
}

Java

public void showMenu(View v) {
    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener
    popup.setOnMenuItemClickListener(this);
    popup.inflate(R.menu.actions);
    popup.show();
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.archive:
            archive(item);
            return true;
        case R.id.delete:
            delete(item);
            return true;
        default:
            return false;
    }
}

Membuat Grup Menu

Grup menu adalah sekumpulan item menu yang sama-sama memiliki ciri (trait) tertentu. Dengan grup, Anda dapat:

Anda dapat membuat kelompok dengan menyarangkan elemen-elemen <item> dalam elemen <group> di resource menu atau dengan menetapkan ID kelompok bersama metode add().

Berikut ini adalah contoh resource menu yang berisi sebuah grup:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_save"
          android:icon="@drawable/menu_save"
          android:title="@string/menu_save" />
    <!-- menu group -->
    <group android:id="@+id/group_delete">
        <item android:id="@+id/menu_archive"
              android:title="@string/menu_archive" />
        <item android:id="@+id/menu_delete"
              android:title="@string/menu_delete" />
    </group>
</menu>

Item yang berada dalam grup akan muncul pada level yang sama dengan item pertama, ketiga item dalam menu adalah bersaudara. Namun, Anda dapat memodifikasi ciri kedua item dalam grup dengan mengacu ID grup dan menggunakan metode yang tercantum di atas. Sistem juga tidak akan memisahkan item yang telah dikelompokkan. Misalnya, jika Anda mendeklarasikan android:showAsAction="ifRoom" untuk setiap item, item tersebut akan muncul dalam panel tindakan atau dalam kelebihan aksi.

Menggunakan item menu yang dapat dicentang

Gambar 5. Cuplikan layar submenu dengan item yang dapat dicentang.

Menu dapat digunakan sebagai antarmuka untuk mengaktifkan dan menonaktifkan opsi, menggunakan kotak centang untuk opsi mandiri, atau tombol radio untuk grup opsi yang saling eksklusif. Gambar 5 menampilkan submenu dengan item yang dapat dicentang dengan tombol radio.

Catatan: Item menu di Menu Ikon (dari menu opsi) tidak dapat menampilkan kotak centang atau tombol radio. Jika Anda memilih untuk membuat item dalam Icon Menu yang dapat dicentang, Anda harus menandai status dicentang secara manual dengan menukar ikon dan/atau teks tiap kali statusnya berubah.

Anda dapat mendefinisikan perilaku yang dapat dicentang untuk setiap item menu dengan menggunakan atribut android:checkable dalam elemen <item> atau untuk seluruh kelompok dengan atribut android:checkableBehavior dalam elemen <group>. Misalnya, semua item dalam grup menu ini dapat dicentang dengan tombol radio:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/red"
              android:title="@string/red" />
        <item android:id="@+id/blue"
              android:title="@string/blue" />
    </group>
</menu>

Atribut android:checkableBehavior menerima:

single
Hanya satu item dari grup ini yang dapat dicentang (tombol radio)
all
Semua item dapat dicentang (kotak centang)
none
Tidak ada item yang dapat dicentang

Anda dapat menerapkan status dicentang default pada suatu item dengan menggunakan atribut android:checked dalam elemen <item> dan mengubahnya dalam kode dengan metode setChecked().

Jika item yang dapat dicentang dipilih, sistem akan memanggil metode callback setiap item yang dipilih (seperti onOptionsItemSelected()). Di sinilah Anda harus mengatur status kotak centang karena kotak centang itu atau tombol pilihan tidak otomatis mengubah statusnya. Anda dapat melakukan kueri status saat ini suatu item (seperti sebelum pengguna memilihnya) dengan isChecked() kemudian mengatur status diberi tanda centang dengan setChecked(). Contoh:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.vibrate, R.id.dont_vibrate -> {
            item.isChecked = !item.isChecked
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.vibrate:
        case R.id.dont_vibrate:
            if (item.isChecked()) item.setChecked(false);
            else item.setChecked(true);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Jika Anda tidak mengatur status diberi tanda centang dengan cara ini, maka status item (kotak centang atau tombol radio) yang terlihat tidak akan berubah bila pengguna memilihnya. Bila Anda telah mengatur status, aktivitas akan menjaga status diberi tanda centang suatu item sehingga bila nanti pengguna membuka menu, status diberi tanda centang yang Anda atur akan terlihat.

Catatan: Item menu yang dapat dicentang dimaksudkan untuk digunakan hanya atas dasar per sesi dan tidak disimpan setelah aplikasi dimusnahkan. Jika Anda memiliki setelan aplikasi yang ingin disimpan untuk pengguna, Anda harus menyimpan data dengan menggunakan Shared Preferences.

Menambahkan Item Menu Berdasarkan Intent

Terkadang Anda ingin agar item menu menjalankan aktivitas dengan menggunakan Intent (baik aktivitas berada dalam aplikasi Anda maupun di aplikasi lain). Bila Anda mengetahui intent yang ingin digunakan dan memiliki item menu tertentu yang harus memulai intent, Anda dapat mengeksekusi intent dengan startActivity() selama metode callback saat-item-dipilih sesuai (seperti callback onOptionsItemSelected()).

Akan tetapi, jika Anda tidak yakin apakah perangkat pengguna berisi aplikasi yang menangani intent, maka menambahkan item menu yang memanggilnya dapat mengakibatkan item menu tidak berfungsi, karena intent tidak dapat diterjemahkan menjadi aktivitas. Untuk mengatasi hal ini, Android memungkinkan Anda menambahkan item menu secara dinamis ke menu bila Android menemukan aktivitas pada perangkat yang menangani intent Anda.

Untuk menambahkan item menu berdasarkan aktivitas tersedia yang menerima intent:

  1. Tentukan intent dengan kategori CATEGORY_ALTERNATIVE dan/atau CATEGORY_SELECTED_ALTERNATIVE, plus kebutuhan lainnya.
  2. Panggil Menu.addIntentOptions(). Android kemudian akan menelusuri setiap aplikasi yang dapat melakukan intent dan menambahkannya ke menu Anda.

Jika tidak ada aplikasi terinstal yang memenuhi intent, maka tidak ada item menu yang ditambahkan.

Catatan: CATEGORY_SELECTED_ALTERNATIVE digunakan untuk menangani elemen yang saat ini dipilih pada layar. Jadi, ini hanya digunakan saat membuat Menu dalam onCreateContextMenu().

Contoh:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    super.onCreateOptionsMenu(menu)

    // Create an Intent that describes the requirements to fulfill, to be included
    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
    val intent = Intent(null, dataUri).apply {
        addCategory(Intent.CATEGORY_ALTERNATIVE)
    }

    // Search and populate the menu with acceptable offering applications.
    menu.addIntentOptions(
            R.id.intent_group,  // Menu group to which new items will be added
            0,                  // Unique item ID (none)
            0,                  // Order for the items (none)
            this.componentName, // The current activity name
            null,               // Specific items to place first (none)
            intent,             // Intent created above that describes our requirements
            0,                  // Additional flags to control items (none)
            null)               // Array of MenuItems that correlate to specific items (none)

    return true
}

Java

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

    // Create an Intent that describes the requirements to fulfill, to be included
    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
    Intent intent = new Intent(null, dataUri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

    // Search and populate the menu with acceptable offering applications.
    menu.addIntentOptions(
         R.id.intent_group,  // Menu group to which new items will be added
         0,      // Unique item ID (none)
         0,      // Order for the items (none)
         this.getComponentName(),   // The current activity name
         null,   // Specific items to place first (none)
         intent, // Intent created above that describes our requirements
         0,      // Additional flags to control items (none)
         null);  // Array of MenuItems that correlate to specific items (none)

    return true;
}

Untuk setiap aktivitas yang diketahui menyediakan filter intent yang cocok dengan intent yang didefinisikan, item menu akan ditambahkan, menggunakan nilai dalam filter intent android:label sebagai sebagai judul item menu dan ikon aplikasi sebagai ikon item menu. Metode addIntentOptions() mengembalikan jumlah item menu yang ditambahkan.

Catatan: Saat Anda memanggil addIntentOptions(), opsi ini mengganti semua item menu dengan grup menu yang ditentukan dalam argumen pertama.

Memungkinkan aktivitas Anda ditambahkan ke menu lain

Anda juga dapat menawarkan layanan aktivitas Anda pada aplikasi lainnya, sehingga aplikasi Anda dapat disertakan dalam menu aplikasi lain (membalik peran yang dijelaskan di atas).

Agar dapat dimasukkan dalam menu aplikasi lain, Anda perlu mendefinisikan filter intent seperti biasa, tetapi pastikan menyertakan nilai-nilai CATEGORY_ALTERNATIVE dan/atau CATEGORY_SELECTED_ALTERNATIVE untuk kategori filter intent. Contoh:

<intent-filter label="@string/resize_image">
    ...
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    ...
</intent-filter>

Baca selengkapnya tentang penulisan filter intent dalam dokumen Intent dan Filter Intent.