09

Tvorba menu

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.


Android umožňuje vytvořit tři základní druhy menu

  1. Menu voleb

  2. Kontextové menu, které se otevírá nejčastěji podržením prstu na prvku (widget, resp. terminologií aplikací pro Android view – tlačítko, textové pole,…), který má toto menu přiřazeno.

  3. Popup menu, které se zobrazuje jako svislý seznam jednotlivých položek.

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.


Menu voleb (options menu)

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



Zobrazení menu v aplikaci

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).


Ošetření výběru položky menu

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


Postup vytvoření menu - shrnutí

  1. Spusťte vývojové prostředí Android Studio, projekt nazvěte „Menu voleb“.

  2. Vyberte konfiguraci pro verzi Android 3.0 a vyšší.

  3. Otevřete ve složce res/values soubor strings.xml a přes tag <string> </string> doplňte názvy položek v menu.

  4. Otevřete ve složce res/menu soubor main_menu.xml a nadefinujte si přes tag <item/> položky v menu. Vyzkoušejte si jednotlivé možnosti nastavení. Zkuste například jednu položku menu zobrazit obrázkem.

  5. Otevřete třídu MainActivity a proveďte ošetření jednotlivých položek.

  6. Spusťte na projekt na svém zařízení nebo virtuálním zařízení (VD) a otestujte.

Vytvoření podmenu

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:

  1. Nahradíme nepárový tag <item/> u položky Info za párový tag <item> </item>

  2. Do něj si nadefinujeme nové menu pomocí tagu <menu> </menu>.

  3. Mezi tyto značky vložíme opět nepárové tagy <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);
}

Úkol: Doplňte menu do projektu Můj pestrý život

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:

  • Klikneme pravým tlačítkem na složku res a vybereme New→ Android Resource Directory a vybereme typ menu.

  • Dále klikneme pravým tlačítkem na nově vytvořenou složku a zvolíme New→ Menu Resource File. Jako typ zadáme Main menu.

Shrnutí:

  • Definování položek menu provádíme v XML souboru uloženém v adresáři res/menu.

  • Položku menu vytvoříme pomocí nepárového tagu <item/>.

  • Chceme-li vytvořit podmenu, nahradíme nepárový tag <item/> za párový a uvnitř definujeme nové menu pomocí párového tagu <menu> a nepárových tagů <item/>.

  • Provázání XML souboru menu s aplikací se stará metoda onCreateOptionsMenu(Menu menu) a metoda getMenuInflater.inflate(...), ve které předáme identifikátor souboru s menu.

  • Díky metodě 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