09
Android samozřejmě umožňuje přiřadit aplikacím menu. V této kapitole si ukážeme základní postup při vytvoření menu voleb. Zmíníme také tvorbu podmenu a ošetření výběru položky z menu. Pro detailnější práci s menu (sdružování do skupin, výčet atributů pro položky menu, aj.) uvedeme pro zájemce odkazy. V další kapitole si pak vyzkoušíme vytvoření kontextového menu.
Všechny typy menu pracují velmi podobně, hlavní rozdíl spočívá v plnění a získání informace o vybraných volbách.
Do verze Android 3.0 (API level 11) bylo menu vyvoláváno speciálním hardwarovým tlačítkem (tři tečky nebo čárky) a zobrazovalo se jako maximálně šest tlačítek uspořádaných v mřížce 2 × 3. Mělo-li menu více položek, šesté tlačítko bylo tvaru šipky, jehož účelem bylo zobrazit zbylé položky menu tak, aby uživatel viděl všechny najednou.

Obrázek 1 – menu se šesti tlačítky
Od verze Android 3.0 se menu objevuje v panelu akcí (pokud je přítomno), případně lze dle nastavení vyvolat kliknutím na příslušnou ikonu.
Tvorbu základního menu voleb si ukážeme na jednoduchém příkladu. Budeme chtít vytvořit menu o čtyřech položkách „Info“, „Kontakt“, „Sdílet“ , „Nastavení“.
Bude výhodné, když pro první příklad použijeme při vytváření projektu šablonu Blank Activity, která už má základ menu nachystán. Jak ale rychle zjistíme, menu si snadno přidáme i pokud jsme použili při vytváření projektu Empty Activity.
Definice jednotlivých položek menu se provádí nejčastěji přes XML soubor(y)1, který je uložen ve složce res/menu2. Jednotlivé názvy položek menu si nastavíme v souboru strings.xml ve složce res/values.
<resources> <string name="app_name">Menu voleb</string> <string name="menu_info">Info</string> <string name="menu_kontakt">Kontakt</string> <string name="menu_sdilet">Sdílet</string> <string name="menu_nastav">Nastavení</string> </resources>
Obrázek 2 – soubor strings.xml
Otevřeme soubormenu_main.xml a přidáme první položku menu „Info“. Android Studio již vytvořilo ukázku jedné volby, proto ji pro náš příklad stačí přepsat.
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/menu_info" android:title="@string/menu_info" android:orderInCategory="100" android:showAsAction="never"/> </menu>
Obrázek 3 – soubor menu_main.xml, zápis jedné položky menu
Jak vidíme ze vzoru, každá položka menu je zapsána tagem <item/>. Jednotlivé atributy tohoto tagu určují další vlastnosti voleb. Mezi nejpoužívanější patří:
android:id – přiřazení identifikátoru k položce menu, pomocí něhož se budeme moci odvolávat na tuto volbu.
android:title – načtení názvu položky ze souboru strings.xml.
android:orderInCategory – určuje pořadí položek v seznamu, čím menší číslo, tím více vlevo či nahoře.
android:showAsAction – určuje, kdy bude položka menu viditelná.
always – položka se umístí na panel akcí.
ifRoom – položka se umístí na panel akcí, pokud je zde místo. Přednost mají položky s menším číslem orderInCategory.
never – položka se nikdy neobjeví na panelu akcí, je přístupná přes ikonu menu.
android:icon – načtení obrázku položky. Ikona se nejčastěji ukládá do složky res/drawable.
android:checkable – určení, zda-li můžeme položku zaškrtnout (true, false).
android:alphabeticShortcut – znaková klávesová zkratka.
android:numericShortcut – číslicová klávesová zkratka.
Tip
Doplňme si do souboru main_menu.xml zbylé 3 hodnoty voleb:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/menu_info" android:title="@string/menu_info" android:orderInCategory="100" android:showAsAction="never"/> <item android:id="@+id/menu_kontakt" android:title="@string/menu_kontakt" android:orderInCategory="100" android:showAsAction="never" /> <item android:id="@+id/menu_sdilet" android:title="@string/menu_sdilet" android:orderInCategory="100" android:showAsAction="never" /> <item android:id="@+id/menu_nastav" android:title="@string/menu_nastav" android:orderInCategory="100" android:showAsAction="never" /> </menu>
Obrázek 4 – kompletní kód pro menu se 4 položkami
Jelikož jsme navolili všechny atributy android:showAsAction na hodnotu „never” zůstávají jednotlivé volby skryty a objeví se až při kliknutí na ikonu menu (tři tečky či čárky). Pokud nastavíme prvním dvou položkám tento atribut na „always” nebo „ifRoom”, uvidíme tyto volby ihned, zatímco zbylé dvě zůstávají skryté.
Obrázek 5 –
Tip
Výhodou Android Studia je, že kód pro použití námi vytvořeného menu, přidává do aktivity automaticky. V souboru java/<nazev_baliku>/MainActivity je přidána metoda public boolean onCreateOptionsMenu(Menu menu).
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; }
V případě, že by se náš soubor s menu (menu_main.xml) jmenoval jinak, přepíšeme pouze v metodě inflate identifikátor tohoto souboru (například mojemenu, pokud se bude soubor jmenovat mojemenu.xml).
Pokud chceme reagovat na uživatelův výběr položky v menu, překryjeme si metodu
public boolean onOptionsItemSelected (MenuItem item). Tato metoda nám prostřednictvím parametru
MenuItem item předává informaci, na kterou položku menu bylo kliknuto. Díky metodě
getItemId() zjistíme číslo identifikátoru dané položky – to jsme si navolili v souboru
main_menu.xml. Po kliknutí na položku menu
Info můžeme tak třeba zobrazit informační bublinu o aplikaci.
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //zjištení identifikátoru zmačklé položky v menu if(id == R.id.menu_info) //porovnání zjištěného identifikátoru s identifikátorem položky INFO { //zobrazení informační bubliny Toast.makeText(this, "Aplikace na ukázku při vytváření menu", Toast.LENGTH_LONG).show(); } return super.onOptionsItemSelected(item); }
Pokud chceme provést ošetření všech položek, využijeme větvení podmínky if – else, případně konstrukce switch - case
<string> </string> doplňte názvy položek v menu.
<item/> položky v menu.
Vyzkoušejte si jednotlivé možnosti nastavení. Zkuste například jednu položku menu zobrazit obrázkem.
V předchozí části jsme si ukázali vytvoření menu voleb, které se skládalo ze čtyř položek na stejné úrovni. Nyní budeme chtít vytvořit podmenu položky Info tak, aby nabízela další dvě volby – Informaci o autorovi a Informaci o aplikaci. Určitě tušíte, že si budeme muset opět pohrát se souborem main_menu.xml. Nejprve ale doplňme nové názvy položek do souboru strings.xml.
<resources> <string name="app_name">Menu voleb</string> <string name="menu_info">Info</string> <string name="menu_kontakt">Kontakt</string> <string name="menu_sdilet">Sdílet</string> <string name="menu_nastav">Nastavení</string> <string name="pod_info_it1">Informace o autorovi</string> <string name="pod_info_it2">Informace o programu</string> </resources>
Přejděme do souboru main_menu.xml a upravme ho. Pokud chceme využít u položky Info podmenu, využijeme párového tagu <item> a do něj si definujeme další menu. Tedy:
<item/> u položky Info za párový tag <item> </item>
<menu> </menu>.
<item/> , které vytvoří další dvě položky v podmenu.
Soubor main_menu.xml bude tedy vypadat takto:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/menu_info" android:title="@string/menu_info" android:orderInCategory="100" android:showAsAction="always"> <menu> <item android:id="@+id/pod_info" android:title="@string/pod_info_it1" android:orderInCategory="100" android:showAsAction="never"/> <item android:id="@+id/pod_info2" android:title="@string/pod_info_it2" android:orderInCategory="100" android:showAsAction="never"/> </menu> </item> <item android:id="@+id/menu_kontakt" android:title="@string/menu_kontakt" android:orderInCategory="100" android:showAsAction="always" /> <item android:id="@+id/menu_sdilet" android:title="@string/menu_sdilet" android:orderInCategory="100" android:showAsAction="never" /> <item android:id="@+id/menu_nastav" android:title="@string/menu_nastav" android:orderInCategory="100" android:showAsAction="never" /> </menu>
Po kliknutí na INFO se objeví seznam vytvořený v podmenu:
Obrázek 7 –
Všimněte si, že informační bublina (Toast) se stále zobrazuje už při kliknutí na volbu Info. Reakci na volby podmenu upravíme stejně jako u voleb menu. Na všechny volby (podmenu i menu) odkazujeme pomocí jejich ID.
Upravený kód metody onOptionsItemSelected(…) bude vypadat takto:
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.pod_info) { Toast.makeText(this, "Aplikace na ukázku při vytváření menu", Toast.LENGTH_LONG).show(); return true; } return super.onOptionsItemSelected(item); }
Doplňte menu voleb do projektu Můj pestrý život z předchozích kapitol. V menu budou volby Znovu načti (zahodí stávající data a načte ze souboru původní verzi) a Ulož (uloží stávající data do souboru).
V projektu již máme připraveny metody Data.nactiData(...) a DataKlientu.ulozData(…). Stačí tedy vytvořit menu voleb a následně tyto metody zavolat, kdykoli uživatel zvolí odpovídající položku menu.
Protože jsme v tomto projektu začínali od Empty Activity, budeme si muset vytvořit pod adresář res/menu i soubor main_menu.xml. Obojí zařídíme v okně Project Android Studia:
<item/>.
<item/> za párový a uvnitř definujeme nové menu pomocí párového tagu <menu> a nepárových tagů <item/>.
onCreateOptionsMenu(Menu menu) a metoda getMenuInflater.inflate(...), ve které předáme identifikátor souboru s menu.
onOptionsItemSelected(MenuItem item)můžeme ošetřit, zda uživatel vybral určitou volbu v menu či podmenu. ID zvolené položky získáme pomocí metody item.getItemId(). ID je číselné a lze tedy porovnávat s hodnotami atributů android:id jednotlivých voleb pomocí příkazů if či switch.
1 Druhou možností je zapsat přímo kód do metody onCreateOptionsMenu(Menu menu) – touto možností se ale zabývat nebudeme
2 Některá vývojová prostředí složku menu nevytváří, nebojte se ji proto ve složce res vytvořit ručně, stejně tak jako soubor menu.xml