Kenapa tombol close menu pop up tidak berfungsi

Anda dapat menggunakan Snackbar untuk menampilkan pesan singkat kepada pengguna. Pesan akan otomatis hilang setelah beberapa saat. Snackbar ideal untuk pesan singkat yang tidak memerlukan interaksi pengguna. Misalnya, aplikasi email dapat menggunakan Snackbar untuk memberi tahu pengguna bahwa aplikasi tersebut berhasil mengirimkan email.

Menggunakan CoordinatorLayout

Snackbar dilampirkan ke tampilan. Snackbar menyediakan fungsionalitas dasar jika dilampirkan ke objek apa pun yang berasal dari class View, seperti salah satu objek tata letak umum. Namun, jika Snackbar dilampirkan ke CoordinatorLayout, Snackbar mendapatkan fitur tambahan:

  • Pengguna dapat menutup Snackbar dengan menggesernya keluar.
  • Tata letak akan memindahkan beberapa elemen UI lain jika Snackbar muncul. Misalnya, jika memiliki FloatingActionButton, tata letak akan memindahkan tombol ke atas saat menampilkan Snackbar, dan bukan menarik Snackbar ke atas tombol. Anda dapat melihat bagaimana tampilannya pada Gambar 1.

Class CoordinatorLayout menyediakan superset fungsionalitas FrameLayout. Jika aplikasi Anda sudah menggunakan FrameLayout, Anda dapat mengganti tata letak tersebut dengan CoordinatorLayout untuk mengaktifkan fungsionalitas Snackbar yang lengkap. Jika aplikasi menggunakan objek tata letak lain, hal paling sederhana untuk dilakukan adalah mengemas elemen tata letak yang ada di CoordinatorLayout, seperti contoh berikut:

<android.support.design.widget.CoordinatorLayout android:id="@+id/myCoordinatorLayout" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Here are the existing layout elements, now wrapped in a CoordinatorLayout --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- …Toolbar, other layouts, other elements… --> </LinearLayout> </android.support.design.widget.CoordinatorLayout>

Pastikan untuk menyetel tag android:id untuk CoordinatorLayout Anda. Anda perlu ID tata letak saat menampilkan pesan.

Kenapa tombol close menu pop up tidak berfungsi

Gambar 1. CoordinatorLayout membuat FloatingActionButton naik saat Snackbar muncul.

Menampilkan pesan

Ada dua langkah untuk menampilkan pesan. Pertama, buat objek Snackbar dengan teks pesan. Kemudian, panggil metode show() objek untuk menampilkan pesan kepada pengguna.

Membuat objek Snackbar

Buat objek Snackbar dengan memanggil metode Snackbar.make() statis. Saat Anda membuat Snackbar, tentukan pesan yang ditampilkannya dan lama waktu untuk menampilkan pesan:

val mySnackbar = Snackbar.make(view, stringId, duration)
Snackbar mySnackbar = Snackbar.make(view, stringId, duration);

lihat Tampilan untuk melampirkan Snackbar. Metode tersebut benar-benar menelusuri hingga hierarki tampilan dari tampilan yang diteruskan hingga mencapai CoordinatorLayout atau tampilan konten dekorasi jendela. Biasanya, cara paling sederhana adalah cukup dengan meneruskan CoordinatorLayout yang menyertakan konten Anda. stringId ID resource pesan yang ingin Anda tampilkan. Ini dapat berupa teks berformat atau tidak berformat. durasi Lamanya waktu untuk menampilkan pesan. Ini dapat berupa LENGTH_SHORT atau LENGTH_LONG.

Menampilkan pesan kepada pengguna

Setelah membuat Snackbar, panggil metode show()-nya untuk menampilkan Snackbar kepada pengguna:

mySnackbar.show()
mySnackbar.show();

Sistem tidak menampilkan beberapa objek Snackbar bersamaan, sehingga jika tampilan saat ini menampilkan Snackbar lain, sistem akan mengantrekan Snackbar Anda dan menampilkannya setelah Snackbar saat ini habis masa berlakunya atau sudah ditutup.

Jika Anda hanya ingin menampilkan pesan kepada pengguna dan tidak perlu memanggil salah satu metode utilitas objek Snackbar, Anda tidak perlu menyimpan referensi ke Snackbar setelah Anda memanggil show(). Karenanya, menggunakan perantaian metode untuk membuat dan menampilkan Snackbar dalam satu pernyataan adalah hal yang biasa:

Snackbar.make( findViewById(R.id.myCoordinatorLayout), R.string.email_sent, Snackbar.LENGTH_SHORT ).show()
Snackbar.make(findViewById(R.id.myCoordinatorLayout), R.string.email_sent, Snackbar.LENGTH_SHORT) .show();

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 utama item menu 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 konten atau bingkai konteks yang dipilih.

Mode tindakan kontekstual menampilkan item tindakan yang memengaruhi konten 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 berpangkal pada tampilan yang memanggil menu. Ini cocok untuk menyediakan tindakan tambahan 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 ranah konten 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 konten 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 tindakan 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, Tampilan, 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.

Kenapa tombol close menu pop up tidak berfungsi

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 sebagai tindakan tambahan, yang dapat ditampilkan pengguna melalui ikon tindakan tambahan 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 tindakan dan perilaku panel aplikasi lainnya, lihat kelas pelatihan Menambahkan Panel Aplikasi.

Kenapa tombol close menu pop up tidak berfungsi

Gambar 2. Aplikasi Google Spreadsheet, menampilkan beberapa tombol, termasuk tombol tindakan tambahan.

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:

override fun onCreateOptionsMenu(menu: Menu): Boolean { val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.game_menu, menu) return true }
@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.

Bila pengguna memilih item dari menu opsi (termasuk item tindakan 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:

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) } }
@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 terlebih 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 yang merespons klik 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 sebagian 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.

Setelah memanggil onCreateOptionsMenu(), sistem akan mempertahankan instance Menu yang Anda tempatkan dan tidak akan memanggil onCreateOptionsMenu() lagi kecuali jika 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 mengupdate menu, Anda harus memanggil invalidateOptionsMenu() untuk meminta sistem memanggil onPrepareOptionsMenu().

Catatan: Anda tidak boleh mengubah item dalam menu opsi berdasarkan View yang saat ini menjadi fokus. 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.

Kenapa tombol close menu pop up tidak berfungsi

Gambar 3. Screenshot 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 tindakan yang memengaruhi item yang dipilih. Bila mode ini aktif, pengguna dapat melakukan tindakan 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.

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(). Inilah tempat Anda mendefinisikan item menu, biasanya dengan meng-inflate resource menu. Contoh:

    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) }
    @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 tindakan yang sesuai. Contoh:

    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) } }
    @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 yang bersangkutan di setiap fragmen, satu per satu (sesuai dengan urutan penambahan tiap 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 tindakan kontekstual. Bila seorang pengguna mengaktifkan mode ini dengan memilih suatu item, 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 kembali, atau memilih tindakan Selesai di sisi kiri panel tindakan.

Catatan: Panel tindakan kontekstual tidak harus diasosiasikan 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 tampilan.
  • Pengguna memilih kotak centang atau komponen UI yang serupa dalam tampilan.

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

  • Untuk tindakan kontekstual pada tampilan sembarang dan tersendiri.
  • Untuk tindakan kontekstual batch atas kelompok item dalam ListView atau GridView (memungkinkan pengguna memilih beberapa item dan melakukan tindakan 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 tindakan, 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:

    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 } }
    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 bahwa contoh di atas menyetel variabel actionMode menjadi null saat 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:

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

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 } }) }
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 tindakan 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().

Kenapa tombol close menu pop up tidak berfungsi

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 jenis overflow (tambahan) untuk tindakan yang berkaitan dengan konten 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 konten 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:

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:

fun showPopup(v: View) { val popup = PopupMenu(this, v) val inflater: MenuInflater = popup.menuInflater inflater.inflate(R.menu.actions, popup.menu) popup.show() }
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.

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:

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 } }
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, kedua item tersebut akan muncul dalam panel tindakan atau keduanya muncul sebagai tindakan tambahan.

Menggunakan item menu yang dapat dicentang

Kenapa tombol close menu pop up tidak berfungsi

Gambar 5. Screenshot 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:

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

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:

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 }
@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.