Programování pro Android: začátky s UI

Lukáš Marek 31. 3. 2011

Původním záměrem tohoto seriálu bylo sepsat pár tipů pro středně pokročilé androidisty. Živá diskuse pod prvním dílem ukázala, že se možná vyplatí „vrátit se ke kořenům“ a sepsat i pár tipů pro úplné začátečníky. Pořád ale platí, že články předpokládají alespoň slušně poučené čtenářské publikum.

Pokud jste úplní začátečníci a nevíte, jak si stáhnout a rozchodit Android SDK, budete si to muset nastudovat jinde.

Dnes se podíváme na vytváření uživatelského rozhraní Android aplikací.

Deklarativní GUI

Zřejmě kvůli co nejvyšší efektivitě využívá Android koncept tzv. deklarativního GUI. To znamená, že uživatelské rozhraní není vytvářeno kódem po jednotlivých krocích (jako je třeba Swing), ale každá obrazovka (nebo její část) je deklarována jako celek. Rozumíme si? Ne?

Prostě místo (pseudo)kódu:

  1. Vytvoř okno
  2. do okna vlož dialog
  3. do dialogu vlož text "Pozor"
  4. do dialogu vlož tlačítko "Ok"

se používá deklarace

  okno:
    obsahuje dialog:
      obsahuje text "Pozor"
      obsahuje tlačítko "Ok"

Deklarace jednotlivých obrazovek jsou napsány v XML (no flame, pls.) a uloženy v projektu v podadresáři res/layout. Při buildu aplikace se XML přeloží do úsporného binárního formátu, který je interpretován telefonem.

Je čas na první příklad. Úvodní obrazovka cvičné aplikace z minulého dílu je deklarována takto:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Zkus MENU -> Vyber kontakt"
    android:id="@+id/napoveda"
    />
</LinearLayout>

Jak je vidět, jde o velice jednoduchou obrazovku, ve které je do kontejneru LinearLayout vložen TextView. Všimněte si, že i délka a šířka jednotlivých prvků je určena relativně – buď má vyplnit celou velikost rodičovského prvku ( fill_parent), nebo má mít minimální potřebnou velikost ( wrap_content).

Atribut android:id slouží k pojmenování konkrétních prvků obrazovky a používá se jak k odkazování mezi jednotlivými prvky v XML, tak poté i v kódu.

Co se v Androidu dostupných prvků týká, jde v vcelku o standardní sadu: obrázek ( ImageView), text ( TextView), tlačítko ( Button) a tak podobně. Zde nezbývá než doporučit samostudium. Samozřejmě, že lze rozšířit nabízenou paletu i o vlastní tvorbu…

Opusťme samotné prvky a věnujme se něčemu zajímavějšímu – jejich rozložení na displeji.

Layouty

Podobně jako již zmíněný Swing, nemá Android moc rád absolutní pozicování prvků na displeji. Požadavek je to celkem logický, byť je díky tomu složitější dobrat se k pěkně vypadajícímu návrhu obrazovky.

A opět podobně jako u Swingu jsou programátorovi k dispozici kontejnery, zde nazývané layouty, které slouží k „rovnání“ jednotlivých komponent. Pojďme se podívat na nejpoužívanější:

LinearLayout

… aneb nejlepší kamarád každého začátečníka. Tento layout je nejvhodnější na učení, protože je relativně přímočarý. Jednoduše všechny do něj vložené prvky srovná do řady a to buď vertikálně ( android:orientation="vertical") nebo horizontálně ( android:orientation="horizontal").

Vzhledem k tomu, že layouty lze vkládat do sebe, dá se i s tímto jednoduchým prostředkem dosáhnout zajímavých výsledků. Bohužel za cenu toho, že vznikne dost rozsáhlý strom vnořených layoutů, což je navýsost nepřehledné pro programátora a výpočetně náročné pro mobil.

RelativeLayout

Z těchto důvodů většina začátečníků brzy přejde na RelativeLayout. Ten vložené prvky pozicuje relativně proti sobě. U prvku je tedy definováno, že je nad, pod nebo vedle nějakého jiného prvku. Pojďme si ukázat příklad:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent" android:layout_width="fill_parent"
    android:layout_margin="10dip" android:gravity="fill_horizontal">

    <ImageView android:layout_height="50dip" android:src="@drawable/icon"
        android:layout_width="50dip" android:id="@+id/photo"
        android:layout_alignParentLeft="true" android:layout_margin="10dip"></ImageView>

    <LinearLayout android:layout_height="wrap_content"
        android:id="@+id/linearLayout1" android:layout_toRightOf="@+id/photo"
        android:layout_alignTop="@+id/photo" android:orientation="vertical"
        android:layout_width="fill_parent">

        <!-- 3 x TextView  -->

    </LinearLayout>

<RelativeLayout>

Zde je definována fotka kontaktu jako ImageView s id photo, který je „přilepen“ k levému okraji obrazovky ( android:layout_alignParentLeft="true") a má pevně definovanou šířku 50dip. No, a to, že LinearLayout, ve kterém jsou vloženy další kontaktní údaje, je vpravo od fotky, je zařízeno atributem  android:layout_toRightOf="@+id/photo".

Typicky se RelativeLayout používá pro základní rozvržení obrazovky, ostatní layouty pak pro pozicování jednotlivých skupin prvků.

ListView

Poslední ze skupiny častěji používaných layoutů je specialista na seznamy – ListView. Ten zobrazuje jednotlivé řádky, umožňuje jejich rolování, postupné načítání a podobné vymoženosti. ListView se používá relativně často a umí toho tolik, že by si zasloužil samostatný článek.

Ostatní layouty

Další nabízené layouty již nemají tak široké použití, nabízejí například rozložení prvků do tabulky ( TableLayout) nebo práci se záložkami ( TabLayout).

Nástroje pro tvorbu UI

Při pohledu na XML kód jednotlivých layoutů a hlavně při pohledu do nápovědy SDK na množství možných parametrů se nabízí otázka, zda neexistuje nějaká jednodušší cesta, než psát desítky XML tagů ručně.

Dobrá zpráva, existuje – Eclipse plugin pro Android obsahuje pěkný klikací editor obrazovek:


Špatná zpráva je, že je stejně nutné se alespoň základní atributy naučit a umět psát „ručně“, protože někdy je třeba editoru trochu pomoci. Většinou ale stačí přepnout se do zobrazení XML, opravit/přidat jeden konkrétní atribut (většinou android:layout_alignXX) a poté pokračovat v práci v „klikátku“.

UI v kódu

Pokud je obrazovka dokonale popsaná, nastává čas ji oživit. To už se dělá v kódu jednotlivých aktivit, zde například přímo v metodě  onCreate().

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.empty);
    ((TextView) findViewById(R.id.napoveda)).setText("Ahoj svete");
  }

Co se tu děje? Metoda setContentView() najde deklaraci obrazovky res/layout/empty.xml a zobrazí ji na displeji. Konkrétně jde o příklad z první kapitoly.

Metoda findViewById() slouží k nalezení prvků podle id, které dostaly v deklarovaném XML. Samozřejmě, že id nemusí mít přiděleny všechny prvky, ale pouze ty, na které se v kódu bude odkazovat. Už méně samozřejmé je, že v různých XML souborech mohou být prvky se stejným id. To může zpřehlednit aplikaci – všechny prvky se stejným významem (např. tačítko OK) se tedy mohou jmenovat stejně.

DIP

Na závěr spíše poznámka pod čarou – rozměry prvků jsou často uváděny v jednotkách dip. To znamená density independent pixel a jak název napovídá, jde o jednotku, která se přizpůsobuje velikosti a rozlišení displeje. Takže obrázek o velikosti 100dip bude mít na všech telefonech zhruba stejnou relativní velikost.

Ohodnoťte jako ve škole:

Průměrná známka 2,00

Našli jste v článku chybu?
Zasílat nově přidané názory e-mailem
Vitalia.cz: Dnešní patolog o mrtvolu téměř nezavadí

Dnešní patolog o mrtvolu téměř nezavadí

Podnikatel.cz: Rošáda v živnostech. Týká se vás?

Rošáda v živnostech. Týká se vás?

Lupa.cz: Babiš: nevím o návodu, jak obejít blokování webů

Babiš: nevím o návodu, jak obejít blokování webů

DigiZone.cz: Mafra varuje před stíháním za pomluvu

Mafra varuje před stíháním za pomluvu

120na80.cz: Tady se vaří padělané léky

Tady se vaří padělané léky

DigiZone.cz: Šlágr TV: pokuta 100 tisíc za on-line

Šlágr TV: pokuta 100 tisíc za on-line

120na80.cz: Zjistěte, zda je vaše klíště infikované

Zjistěte, zda je vaše klíště infikované

120na80.cz: 10 nej přípravků na holení

10 nej přípravků na holení

120na80.cz: 10 dezinfekcí: Vede „starý dobrý“ peroxid

10 dezinfekcí: Vede „starý dobrý“ peroxid

Podnikatel.cz: Šizený guláš na pultě. Jako Lidl to nedělejte

Šizený guláš na pultě. Jako Lidl to nedělejte

120na80.cz: Poznáte, který z léků je pravý?

Poznáte, který z léků je pravý?

Podnikatel.cz: Heureka pod Rockaway? Tohle musí splnit

Heureka pod Rockaway? Tohle musí splnit

DigiZone.cz: Šlágr TV dostala pokutu 100 000 Kč

Šlágr TV dostala pokutu 100 000 Kč

Lupa.cz: Válka e-shopů. Alza končí s Heurekou

Válka e-shopů. Alza končí s Heurekou

Podnikatel.cz: Miliony hodin nad hlášením k DPH. K vzteku

Miliony hodin nad hlášením k DPH. K vzteku

Podnikatel.cz: Různé podoby lahve Coca–Coly. Úchvatné

Různé podoby lahve Coca–Coly. Úchvatné

Lupa.cz: Přenos hokeje padal kvůli útoku, tvrdí O2

Přenos hokeje padal kvůli útoku, tvrdí O2

Vitalia.cz: 10 rad šéfkuchařů pro perfektní grilování

10 rad šéfkuchařů pro perfektní grilování

DigiZone.cz: Deset let od 1. kulatého stolu DigiZone.cz

Deset let od 1. kulatého stolu DigiZone.cz

Vitalia.cz: Proč máme prasklý chléb nejraději?

Proč máme prasklý chléb nejraději?