Kreiranje sadržaja menija
Ovaj specifični meni se prikazuje u sklopu
Gde se nalaze meniji?
Za svaki meni je potrebno definisati stavke koje se nalaze u njemu. To se definiše u XML formatu u fajlu koje se nalazi u specifičnom folderu pod nazivom “menu” (nalazi se u sklopu “res” foldera). Ovaj fajl generišemo desnim klikom na folder “menu” u project sekciji i izborom New / “Menu resurse file” opcije.
1 2 3 4 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> // ovde ide sadržaj menija </menu> |
Atributi item elementa menija
Stavke menija se definišu kroz element <item/> koji može imati definisane mnoge atribute, najčešće korišćeni atributi su sledeći:
- id (android:id=”@+id/delete”)
- title (android:title=”@string/delete”)
- icon (android:icon=”@drawable/ic_delete”)
- enabled (android:enabled=”false”)
- checkable (android:checkable=”true”)
- showAsAction (Ovi atributi su vezani za prikazivanje elemenata “options menija”u okviru action bar-a )
- ifRoom (app:showAsAction=”ifRoom”)
- withText (app:showAsAction=”withText”)
- never (app:showAsAction=”never”)
- always (app:showAsAction=”always”)
Primer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/edit_menu_item" android:title="@string/edit" android:checkable="true" android:checked="true" android:icon="@drawable/ic_mode_edit" /> <item android:id="@+id/make_default" android:title="@string/make_default" android:checkable="true" android:checked="true"/> <item android:id="@+id/delete_menu_item" android:title="@string/delete" android:icon="@drawable/ic_delete" /> </menu> |
Grupe
Moguće je okupiti slične članove menija u grupe:
1 2 3 4 5 6 |
<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> |
Podmeni
Pravljenje podmenija je jednostavno, u sklopu “item” elementa treba ugraditi novi “menu” element:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/edit_menu_item2" android:icon="@drawable/ic_mode_edit" android:title="@string/edit" app:showAsAction="ifRoom" /> <item android:id="@+id/options_menu" android:icon="@drawable/ic_device_hub_black" android:title="Options"> <menu> <item android:id="@+id/subMenu1" android:title="Submenu1"/> <item android:id="@+id/subMenu2" android:title="Submenu2"/> </menu> </item> </menu> |
NAPOMENA:
Kod elemenata kod kojih se koristi atribut android:checkable=”true” je nakon klika na ovakav član menija potrebno da podesite stanje u polju za potvrdu, jer checkBox (ili radio dugme) ne menja automatski svoje stanje. Nakon klika moramo da upitamo kakvo je stanje stavke bile pre ovog klika (da li je bilo čekirano) koristeći isChecked().
Ako je prethodno bilo čekirano onda sada nakon klika više nije i moramo da stavimo stanje setChecked(false) i obrnuto ako nije bilo čekirano
item.isChecked()=false sada posle klika jeste i moramo da stavimo
item.setChecked(true);
1 2 3 4 5 6 7 8 9 10 11 |
switch (item.getItemId()) { case R.id.make_default: if (item.isChecked()){ item.setChecked(false); Toast.makeText(this, "Sada više nije čekirano", Toast.LENGTH_SHORT).show(); }else { item.setChecked(true); Toast.makeText(this, "Sada je čekirano", Toast.LENGTH_SHORT).show(); } return true; } |
Kreiranje sadržaja menija
Prvo je potrebno definisati sadržaj menija u XML formatu.
Primer (neki_menu.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <item android:checkable="true" android:id="@+id/make_default" android:title="@string/make_default" /> <item android:id="@+id/save" android:title="@string/save" /> <item android:id="@+id/remove" android:title="@string/remove" /> </menu> |
U ovome primeru prvi element menija je tzv. checkbox.
Integrisanje menija u aktivnost
Nakon definisanja sadržaja je potrebno da se omogući da taj meni bude dostupan u aktivnosti.
Primer
1 2 3 4 5 6 |
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.neki_menu, menu); } |
Registrovanje dugmeta koje otvara meni
U sklopu aktivnosti je potrebno registrovati dugme (u onCreate() metodi) koje će biti povezano za taj meni:
1 2 3 4 |
ImageView ivOptionsMenuBtn; ivOptionsMenuBtn = findViewById(R.id.ivOptionsDots); registerForContextMenu(ivOptionsMenuBtn); |
A zatim zakačiti clickListener za njega koji će na klik da pozove metodu openContextMenu(view):
1 2 3 4 5 6 |
ivOptionsMenuBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openContextMenu(v); } }); |
Definisanje šta će da se dogodi klikom na člana menija
U metodi onContextItemSelected() definišemo šta će da se desi klikom na neki od članova menija. Za selektovnanje člana menija se koristi “id” itema definisanog u XML-u (neki_menu.xml):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.make_default: Toast.makeText(this, "Make default", Toast.LENGTH_SHORT).show(); return true; case R.id.save: Toast.makeText(this, "Save", Toast.LENGTH_SHORT).show(); return true; case R.id.remove: Toast.makeText(this, "Remove", Toast.LENGTH_SHORT).show(); return true; default: return super.onContextItemSelected(item); } } |
Options meni
Za options meni nije potrebno da se definiše dugme koje će da reaguje na klik i otvori ovaj meni, zato što ovo dugme android sam ubacuje u action bar i dodeljuje mu ikonicu sa tri vertikalne tačke.
Treba naglasiti da ovde imamo priliku definišemo koji će član menija u biti odmah prikazan u actionBar-u pored options ikone (tri vertikalne tačke). Ovo se obezbedjuje sa atributom app:showAsAction="ifRoom". Options meni se prikazuje baš na mestu kliknutog dugmeta. Ukoliko se neki član prikazuje odmah u action baru on se onda ne nalazi u samom meniju.
Kreiranje sadržaja menija
Pored ovih specifičnosti kao i kod svih drugih menija i ovde je neophodno da se definiše sadržaj menija u XML formatu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?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:id="@+id/share" android:icon="@drawable/ic_device_hub_black" android:title="device" app:showAsAction="ifRoom" /> <item android:id="@+id/edit_menu_item" android:icon="@drawable/ic_mode_edit" android:title="@string/edit" /> <item android:id="@+id/make_default" android:checkable="true" android:title="Make default" /> <item android:id="@+id/delete_menu_item" android:title="@string/delete" android:icon="@drawable/ic_delete" /> <item android:id="@+id/exit" android:title="Exit" /> </menu> |
Integrisanje menija u aktivnost
Na sličan način kao kod Context Float menija se i ovde integriše meni:
1 2 3 4 5 6 |
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater =getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); return true; } |
Definisanje šta će da se dogodi klikom na člana menija
U metodi onOptionsItemSelected definišemo šta će da se desiti nakon klika na neki od članova menija:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.share: Toast.makeText(this, "Share", Toast.LENGTH_SHORT).show(); return true; case R.id.edit_menu_item: Toast.makeText(this, "Edit", Toast.LENGTH_SHORT).show(); return true; case R.id.make_default: if (item.isChecked()){ item.setChecked(false); Toast.makeText(this, "Is not default", Toast.LENGTH_SHORT).show(); }else { item.setChecked(true); Toast.makeText(this, "Is default", Toast.LENGTH_SHORT).show(); } return true; case R.id.delete_menu_item: Toast.makeText(this, "Delete", Toast.LENGTH_SHORT).show(); return true; case R.id.exit: Toast.makeText(this, "Exit", Toast.LENGTH_SHORT).show(); return true; default: return super.onOptionsItemSelected(item); } } |
PopUp meni
Ovaj meni je specifičan jer je vezan za mesto gde je kliknuto. Meni se prikazuje tamo gde ima prostora ili ispod kliknutog mesta, ili iznad kliknutog mesta. PopUp meni se sakriva sa ekrana kada korisnik klikne na neki član menija ili negde sa strane van menija.
Definisanje šta će da se dogodi klikom na člana menija
Da bi klasa (npr. aktivnost) mogla da izvrši akcije nakon klika potrebno je da klasa implementira interfejs PopupMenu.OnMenuItemClickListener.
Nakon imeplementiranja interfejsa je potrebno da se implementira (Override) i njegova abstraktna metoda onMenuItemClick(), kroz koju nam je omogućeno da definišemo za svaki član menija koja će akcija biti preduzeta nakon klika na član.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Override public boolean onMenuItemClick(MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.edit_menu_item: Toast.makeText(this, "Edit", Toast.LENGTH_SHORT).show(); return true; case R.id.delete_menu_item: Toast.makeText(this, "Delete", Toast.LENGTH_SHORT).show(); return true; case R.id.make_default: Toast.makeText(this, "MakeDefault", Toast.LENGTH_SHORT).show(); return true; default: return false; } } |
Integrisanje menija u aktivnost
Da bi prikazali PopUp meni potrebno je da na okidaču (npr. neko dugme) definišemo onClick metodu (npr. shoPopup()) koja izgleda ovako:
1 2 3 4 5 6 7 8 9 10 |
public void showPopup (View v){ PopupMenu popup = new PopupMenu(this, v); // Dodavanje listenera na svaki član menija popup.setOnMenuItemClickListener(this); //Povezivanje sa sadrzajem menija MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.popup_menu, popup.getMenu()); // Prikazivanje menija popup.show(); } |
Contextual Action Mode meni
Ovaj specifični meni se prikazuje u sklopu actionBar-a, tačnije preko actionBar-a se. Pored članova menija prikazanih ikonama u desnom kraju, nalazi se i naslov menija u sredini, i strelica za zatvaranje menija na levoj strani.
Kreiranje sadržaja menija
Kao i za svaki meni prvo je potrebno napraviti sadržaj menija u xml formatu (New “Menu resurse file”) u folderu “menu”
Primer (context_action_menu.xml)
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/edit_menu_item" android:title="@string/edit" android:icon="@drawable/ic_mode_edit" /> <item android:id="@+id/delete_menu_item" android:title="@string/delete" android:icon="@drawable/ic_delete" /> </menu> |
Definisanje ActionModeCallback metode
Pre svega u sklopu aktivnosti je potrebno definisati promenjivu tipa ActionMode (napomena izabrari verziju v.7) jer se ona koristi u okviru callback metode:
1 |
private ActionMode mActionMode; |
A zatim i ActionModeCallback instancu u kojoj se vrši sav posao u vezi Contextual Action Mode menijem. Ima 4 metode, u prvoj onCreateActionMode() se povezuje predhodno definisan sadržaj menija sa Action Mode menijem. U metodi onActionItemClicked() se definišu akcije nakon klika na neki od članova. A ono šta se dešava kada se meni zatvori se definiše u metodi onDestroyActionMode().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { // Povezivanje prethodno definisanog sadržaja sa ovim tipom menija actionMode.getMenuInflater().inflate(R.menu.context_action_menu, menu); // Definisanje Title menija actionMode.setTitle("Izaberite opciju"); return true; } @Override public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { //Definisanje akcije na klik svakog člana menija switch (menuItem.getItemId()) { case R.id.edit_menu_item: // Akcija koja se odvija nakon klika na neki član menija: Toast.makeText(MainActivity.this, "Editujemo nešto", Toast.LENGTH_SHORT).show(); // Možemo da zatvorimo meni nakon klika na izbor actionMode.finish(); return true; case R.id.delete_menu_item: Toast.makeText(MainActivity.this, "Brišemo nešto", Toast.LENGTH_SHORT).show(); // Možemo da zatvorimo meni nakon klika na izbor actionMode.finish(); return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode actionMode) { // Definišemo vrednost ActionMode po zatvaranju menija mActionMode = null; } }; |
Registrovanje dugmeta koje otvara meni
U sklopu aktivnosti je potrebno na odredjenom dugmetu definisati clickListener (u onCreate() metodi) sa kojim ćemo omogućiti da se na klik pozove prethodno definisana callback metoda mActionModeCallback():
1 |
mActionMode = startSupportActionMode(mActionModeCallback); |
Pa bi ceo kod za listener ovako izgledao:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Button btnContextActionMenu = findViewById(R.id.btnContextActionMenu); btnContextActionMenu.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { // Ako je aktivan menu vratiti false if(mActionMode != null){ return false; } // Ako je nekativan onda ga aktiviramo mActionMode = startSupportActionMode(mActionModeCallback); return true; } }); |