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