V Android vývoji je často zdůrazňováno, že nejlepší praxí je vytvářet uživatelské rozhraní (UI) pomocí XML souborů, nikoli přímo v kódu. Přesto existují situace, kdy je nutné menu konstruovat nebo upravovat přímo během běhu aplikace, tedy dynamicky v Java či Kotlin kódu. Typickým příkladem je potřeba zobrazit či skrýt položku menu na základě vnějších podmínek, například zda je uživatel přihlášen.
V tomto přístupu je menu vytvářeno metodou onCreateOptionsMenu(), kde místo tradičního "nafouknutí" (inflace) menu z XML zdroje využíváme metodu Menu.add(). Každá položka menu je definována vlastním ID, což umožňuje jejich následnou manipulaci a rozpoznávání při výběru. Když uživatel otevře menu, Android zavolá tuto metodu, aby menu vykreslil.
Zásadní je také metoda onPrepareOptionsMenu(), která umožňuje upravovat vlastnosti položek menu přímo před jejich zobrazením. Zde můžeme například nastavovat viditelnost určité položky podle hodnoty nějaké proměnné (flagu). V praxi tak lze třeba na základě boolean proměnné showDownloadMenu rozhodnout, zda se nabídka "Download" zobrazí, či nikoli.
Pokud je potřeba změnit stav menu za běhu – například po kliknutí na tlačítko, které má přepínat viditelnost položky – musíme zavolat invalidateOptionsMenu(). Tento příkaz Androidu sdělí, že menu již není aktuální, a spustí znovu metodu onPrepareOptionsMenu(), kde proběhne aktualizace. Bez tohoto kroku by se změny nemusely projevit okamžitě.
Dále lze zlepšit uživatelský zážitek tím, že určitou důležitou položku, například "Download", umístíme přímo do Action Baru. K tomu slouží metoda menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS), která zajistí, že položka bude viditelná trvale na hlavním panelu akčních tlačítek, nikoli jen v rozbalovacím menu. Tento přístup však vyžaduje správné použití invalidateOptionsMenu(), protože Android v takovém případě může menu považovat za "otevřené" a nemusí volat onPrepareOptionsMenu() automaticky při každém zobrazení.
Reakce na výběr položky menu se řeší přepsáním metody onOptionsItemSelected(). Pomocí přepínače (switch) rozlišujeme jednotlivé ID položek a podle toho spouštíme odpovídající akce, například zobrazení Toast zprávy.
Kromě možnosti vytvářet a modifikovat menu dynamicky existují i různé typy kontextových menu. Starší metoda, tzv. floating context menu, je podobná klasickému menu, ale má omezené možnosti, například neumožňuje jasné označení vybrané položky nebo hromadné operace na více položkách najednou. Novější a preferovaný způsob je tzv. Contextual Action Mode, který aktivuje kontextovou akční lištu (Contextual Action Bar, CAB) a umožňuje intuitivní práci s více vybranými položkami, například ve správě emailů.
Pro správnou implementaci kontextových menu je nutné rozlišit, kdy použít metody jako onCreateContextMenu() a onContextItemSelected() u starších verzí Androidu, a kdy využít moderní Contextual Mode, který přináší výrazně lepší uživatelskou zkušenost.
Pochopení tohoto mechanismu je klíčové nejen pro vytváření flexibilních a uživatelsky přívětivých aplikací, ale také pro správné řízení životního cyklu UI komponent a efektivní reakci na uživatelské akce v různých situacích.
Důležité je také chápat, že dynamická změna menu může být řízena nejrůznějšími interními stavy aplikace, a to nejen jednoduchými boolean flagy. Může to být například aktuální stav přihlášení, úroveň uživatele v aplikaci, přítomnost dat k nahrání, nebo dokonce externí signály jako push notifikace. Proto je správné navrhnout menu tak, aby bylo co nejvíce adaptabilní a uživateli nabízelo jen relevantní možnosti.
Jak implementovat funkce pro ovládání blesku a notifikace v Android aplikaci
Pro implementaci funkce ovládání blesku a vytváření notifikací v aplikaci na platformě Android je potřeba pochopit několik klíčových aspektů, které se týkají jak interakce s hardwarem, tak správného zpracování notifikací a akcí. Tento proces se skládá z několika kroků, které zahrnují úpravu základních součástí aplikace, správu stavu blesku a návrh uživatelského rozhraní.
Nejdříve je potřeba upravit soubor AndroidManifest.xml, aby aplikace měla přístup k požadovaným oprávněním a specifikovala komponenty, které jsou nezbytné pro interakci s hardwarem, zejména s kamerou, která je zodpovědná za svítilnu. Poté přecházíme k úpravám v souboru activity_main.xml, kde se vkládá komponenta, která bude sloužit pro zapínání a vypínání blesku, obvykle ve formě tlačítka. Tento prvek je pak propojen s funkcí v kódu, která ovládá svítilnu.
Dále v souboru ActivityMain.java přidáme globální proměnné pro správu stavu blesku a kamerového systému:
Pro správu samotného blesku je třeba v metodě onCreate() nastavit správné parametry pro tlačítko a kamerový manažer:
Pokud není k dispozici kamera s bleskem, tlačítko pro zapnutí/vypnutí blesku bude neaktivní. Pokud je kamera k dispozici, uživatel bude moci ovládat její funkce.
V další fázi je třeba vytvořit metodu, která bude reagovat na akce spojené s notifikacemi, jako například vypnutí blesku prostřednictvím notifikace:
Metoda getCameraId() je zodpovědná za nalezení dostupného ID kamery, která má funkci blesku. Tento kód prochází seznam kamer a vrací ID kamery, která má blesk a je orientována na zadní stranu zařízení, což je obvykle kamera, která je určena pro fotografování.
Poté, co máme ID kamery, můžeme přistoupit k implementaci metod pro samotné ovládání blesku. K tomu slouží metoda, která reaguje na kliknutí na tlačítko pro zapnutí/vypnutí světla, a metoda pro nastavení stavu blesku:
Nakonec musíme implementovat metodu, která vytváří notifikaci. Tato notifikace informuje uživatele o stavu blesku a umožňuje mu vypnout světlo přímo z notifikačního panelu:
Tato metoda generuje notifikaci, která obsahuje informace o stavu blesku a umožňuje uživateli jeho vypnutí stisknutím notifikace. Zajímavým aspektem je zde nastavení setPriority(PRIORITY_MAX), které zajišťuje, že notifikace bude vysoce prioritní a v případě potřeby bude zobrazená jako Heads-Up notifikace, tedy s upozorněním i na zamčené obrazovce.
Před tím, než aplikaci spustíte na zařízení, je třeba mít Android 6.0 nebo vyšší verzi a zařízení vybavené zadní kamerou s bleskem. Po spuštění aplikace bude uživatel moci ovládat svítilnu pomocí tlačítka v aplikaci nebo prostřednictvím notifikace.
Pro zajištění správné funkčnosti této aplikace je důležité věnovat pozornost správné implementaci ovládání notifikací a využívání jejich priorit, protože bez nastavení vysoké priority (ať už pomocí vibrací nebo zvuku) by notifikace nemusely být dostatečně nápadné pro uživatele.
Jak vytvořit animaci přiblížení s vlastní přechodovou animací
V předchozím návodu jsme se naučili vytvářet animaci překlápění karty s pomocí fragmentů. Tento recept se zaměří na vytvoření efektu přiblížení (zoom) pomocí animačních prostředků napsaných v kódu. Aplikace zobrazuje náhledový obrázek, který se po stisknutí zvětší do plné velikosti. Příklady animace přiblížení lze vidět na třech snímkách obrazovky, které ukazují, jak animace vypadá v praxi.
Před začátkem je potřeba vytvořit nový projekt v Android Studiu. Pojmenujte ho a vyberte výchozí možnosti pro telefon a tablet s prázdnou aktivitou. Pro tento projekt použijeme obrázek, který jsme stáhli z webu www.Pixabay.com, ale samozřejmě můžete použít jakýkoli obrázek, který se vám líbí.
Začněme s přípravou. Nejprve zkopírujte obrázek do složky res/drawable a přejmenujte jej na image.jpg (nebo zachovejte původní formát souboru).
Nyní otevřete soubor activity_main.xml a nahraďte jeho obsah následujícím kódem. Tím připravíme základní rozložení pro náhledový obrázek a rozšířený obrázek, který se bude zobrazovat po animaci.
Následuje kód pro aktivitu MainActivity.java, kde deklarujeme potřebné proměnné:
Dále přidejte metodu loadSampledResource(), kterou jsme použili při zmenšování velkých obrázků, aby se předešlo výjimkám OutOfMemory. Tento postup je užitečný, když máme velké obrázky, které by mohly způsobit problémy s pamětí.
Dále přidáme do metody onCreate() kód, který nastaví náhledový obrázek a nastaví posluchače pro kliknutí:
Nyní přidáme metodu zoomFromThumbnail(), která bude provádět samotnou animaci:
Při spuštění aplikace na zařízení nebo emulátoru se obrazovka nejprve zobrazí s náhledovým obrázkem. Po kliknutí na obrázek se spustí animace, která zvětší obrázek na celou obrazovku, přičemž zachová všechny proporce a umístění na obrazovce.
V této implementaci je kladeno důraz na hladké přechody mezi dvěma stavy obrázku. K tomu se používají výpočty pro určení správného měřítka a pozice obrázku. Při animaci přiblížení se využívá vlastnosti AnimatorSet, která zajišťuje, že všechny animační efekty probíhají současně a v jedné ucelené sekvenci.
Důležitým aspektem tohoto procesu je správné zpracování rozlišení obrázků. Při použití obrázků s vysokým rozlišením je důležité zvolit metodu, která zajistí, že obrázky budou načítány s odpovídajícím rozlišením, aby nedocházelo k problémům s pamětí.
Pro lepší optimalizaci animací a udržitelnost aplikace byste měli přemýšlet o použití efektivních metod pro správu paměti při práci s obrázky, zejména pokud pracujete s velkými grafickými soubory. Zajistíte tím plynulost aplikace, která nebudou zatěžovat výkon zařízení.
Jak funguje preview a zachycení obrazu v Android Camera2 API?
Při práci s novou Camera2 API na platformě Android se celý proces rozděluje do dvou základních kroků: nastavení náhledu (preview) a zachycení fotografie. I když se může zdát, že metoda takePicture() je jednoduchá a přímočará, skutečnost je složitější a zahrnuje více tříd a callbacků.
Nejprve se nastaví listener na objekt TextureView pomocí metody setSurfaceTextureListener() ve funkci onCreate(). Jakmile je textura dostupná (onSurfaceTextureAvailable()), otevíráme kameru voláním openCamera(), ke kterému předáme objekt CameraDevice.StateCallback. Po úspěšném otevření kamery (callback onOpened()) získáme SurfaceTexture, který se následně předá k vytvoření CaptureSession přes createCaptureSession(). Jakmile je relace nakonfigurována (onConfigured()), zahájí se náhled opakovaným posíláním požadavků přes setRepeatingRequest().
Samotné zachycení obrazu začíná kliknutím uživatele na tlačítko pro pořízení snímku. Kamera je dotázána na největší dostupnou velikost obrázku, podle které se vytvoří ImageReader. Tento ImageReader je vybaven OnImageAvailableListenerem, který zajistí uložení obrazu při jeho dostupnosti. Následně se sestaví CaptureRequest.Builder, do kterého je přidána plocha ImageReaderu. Pro zachycení snímku se vytváří CameraCaptureSession.CaptureCallback, který definuje chování po dokončení snímání, například opětovné spuštění náhledu. Vytvořená CaptureSession se pomocí createCaptureSession() inicializuje a metoda capture() pak zahajuje samotné zachycení obrazu.
Základní implementace, jaká je zde popsána, funguje, ale je nutné vzít v úvahu další aspekty. Jedním z nich je správná orientace zařízení, která ovlivňuje jak náhled, tak výsledný uložený snímek. Dále je důležité aplikovat moderní model udělování oprávnění, zavedený v Android 6.0 (API 23), kdy je potřeba explicitně kontrolovat a žádat o potřebná oprávnění během běhu aplikace, nikoli pouze spoléhat na výjimky při otevírání kamery.
Vedle toho stojí za zmínku, že API je navrženo modulárně a vyžaduje detailní pochopení životního cyklu kamerových komponent a jejich callbacků. To umožňuje větší flexibilitu, ale také znamená zvýšenou komplexnost oproti starším API.
Pro správné používání Camera2 API je tedy klíčové důkladné plánování stavu aplikace, správné spravování povolení i orientace zařízení a důsledné zpracování callbacků, které umožňují efektivní a plynulé zachytávání obrazu v reálném čase.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский