10

Kontextové menu

V minulé kapitole jsme si ukázali, jak vytvořit hlavní menu aplikace (options menu). Dalším typem menu je tzv. kontextové menu, které se aktivuje podržením prstu na daném widgetu (grafický prvek – například tlačítko, textové pole, …), ke kterému je toto menu přiřazeno. Kontextové menu se zobrazuje dvěma způsoby:

  1. Menu se zobrazí jako plovoucí svislý seznam položek.

  2. Menu se zobrazí v panelu akcí (dostupný od verze Android 3.0).


Postup vytvoření je prakticky velmi podobný jako pro menu voleb:

  1. Definujeme si řetězce v souboru strings.xml, které popisují jednotlivé položky kontextového menu.

  2. Vytvoříme si xml soubor, ve kterém si definujeme položky menu, ten opět umístíme do složky res/menu.

  3. Naimplementujeme metodu onCreateContextMenu(), čímž určíme, které menu se vytvoří.

  4. V aktivitě aplikace určíme, které widgety mají mít kontextové menu – registraci menu pro daný widget provedeme metodou registerForContextMenu(), které předáme instanci třídy View (widget).

  5. Implementujeme metodu onContextItemSelected() pomocí které zjistíme, jakou položku menu uživatel vybral.


Příklad:

Vytvoříme aktivitu s jedním textovým polem, kterému bude přiřazeno kontextové menu. Pomocí něj budeme moci měnit vzhled textu v poli (tučně, kurzíva či opět normálně).


Postup:

  1. Vytvoříme nový projekt s jednoduchou aktivitou obsahující jedno textové polem s textem „Pokusný text“. Android studio nám tuto aktivitu s widgetem TextView vytvoří samo. Doplníme si do návrhu jen id prvku, jelikož se na něj budeme chtít odkazovat (registrovat mu menu):

  2. <TextView android:id="@+id/text1" android:text="@string/pokus" android:layout_width="wrap_content"  android:layout_height="wrap_content" />
    

    Obrázek 1- layout aktivity_main.xml


  3. Do souboru strings.xml ve složce res/values dopíšeme položky kontextového menu.

  4. <resources>
        <string name="app_name">KontextMenu</string>
        <string name="action_settings">Settings</string>
        <string name="pokus">Pokusný text</string>
        <string name="km_kurziva">Kurzíva</string>
        <string name="km_tucne">Tučně</string>
        <string name="km_normal">Normálně</string>
    </resources>
    

    Obrázek 2 – soubor strings.xml


  5. Ve složce res/menu vytvoříme nový soubor menu_pismo.xml a nadefinujeme si zde jednotlivé položky kontextového menu (princip je stejný jako u klasického menu).

  6. <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/km_kurziva" android:title="@string/km_kurziva"
            android:orderInCategory="100" app:showAsAction="never" />
        <item android:id="@+id/km_tucne" android:title="@string/km_tucne"
            android:orderInCategory="100" app:showAsAction="never" />
        <item android:id="@+id/km_normal" android:title="@string/km_normal"
            android:orderInCategory="100" app:showAsAction="never" />
    </menu>
    

    Obrázek 3 – soubor menu_pismo.xml


  7. Přejdeme do souboru MainActivity.java a naimplementujeme si metodu onCreateContextMenu(), ve které díky instanci třídy MenuInflater a metodě inflate() svážeme menu s xml souborem menu_pismo.

  8. @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_pismo, menu);
    }
    

    Obrázek 4 – metoda onCreateContextMenu()


    Metoda onCreateContextMenu() se volá pokaždé, když je kontextové menu potřeba.


  9. V metodě create() doplníme kód, který nalezne widgetu (textového pole) pomocí metody findViewById(). Tomuto poli zaregistrujeme kontextové menu.

  10. @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        registerForContextMenu((TextView)findViewById(R.id.text1));
    }
    

    Obrázek 5 – registrace menu u komponenty TextView


  11. Ošetříme si výběr položky menu – naimplementujeme metodu onContextItemSelected. Tato metoda předává informaci o položce menu (MenuItem), kterou uživatel vybral. Přes podmíněný příkaz či konstrukci switch-case ošetříme všechny možnosti. K jednotlivým položkám menu opět přistupujeme pomocí třídy R. Id položky zjistíme pomocí metody getItemId() volané nad objektem menuItem:

  12. @Override
    public boolean onContextItemSelected(MenuItem item) {
        TextView pole = (TextView)findViewById(R.id.text1);
        switch (item.getItemId()) {
            case R.id.km_kurziva:
                pole.setTypeface(null, Typeface.ITALIC);
                return true;
            case R.id.km_tucne:
                pole.setTypeface(null, Typeface.BOLD);
                return true;
            case R.id.km_normal:
                pole.setTypeface(null, Typeface.NORMAL);
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }
    

    Obrázek 6 – zjištění vybrané položky


    Projekt přeložíme a spustíme na testovacím zařízení. Uvidíme obrazovku s jedním textovým polem. Pokud podržíme prst na tomto poli, otevře se kontextové menu a můžeme vybrat akci.


    Obrázek 7 – aplikace s kontextovým menu


Shrnutí:

  1. Kontextové menu se nejčastěji používá pro widgety a vyvolává se podržením prstu na daném widgetu.

  2. Implementace je podobná jako u menu voleb, kontextové menu je pouze třeba zaregistrovat u widgetu metodou registerForContextMenu().