Kde se v Android projektu používá XML
Klasické Android UI (systém View) odděluje vzhled od logiky: co je na obrazovce, popisuje XML, co se stane po kliknutí, řeší kód. XML ale najdeš i mimo obrazovky:
| Soubor nebo složka | Obsah |
|---|---|
| AndroidManifest.xml | popis aplikace: aktivity, služby, oprávnění, ikona |
| res/layout/ | rozvržení obrazovek a položek seznamů |
| res/values/ | texty (strings.xml), barvy, rozměry, styly a motivy |
| res/drawable/ | vektorové obrázky, tvary a výběry stavů (selector) |
| res/menu/, res/navigation/ | menu a navigační grafy |
| res/xml/ | další konfigurace: nastavení, pravidla zálohování, síťová bezpečnost |
Google dnes pro nové obrazovky doporučuje Jetpack Compose, kde se UI píše přímo v Kotlinu. XML layouty tím nezmizely — běží na nich většina existujících aplikací a manifest, texty, motivy i vektorové ikony zůstávají v XML i v projektech s Compose.
Layout: strom prvků
Soubor v res/layout/ je strom: kořen je kontejner (LinearLayout,
FrameLayout, ConstraintLayout…), listy jsou ovládací prvky. Název
elementu je přímo název třídy Viewu:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/nadpis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/vitejte"
android:textSize="20sp" />
<Button
android:id="@+id/pokracovat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/mezera"
android:text="@string/pokracovat" />
</LinearLayout> -
Všechny atributy frameworku patří do jmenného prostoru
http://schemas.android.com/apk/res/android, který se podle konvence váže na prefixandroid. Bez deklaracexmlns:androidna kořeni se layout nezkompiluje. -
Každý prvek musí mít
layout_widthalayout_height. Atributy s předponoulayout_nejsou vlastnosti prvku samotného, ale pokyny pro jeho rodiče. -
Prvky z knihoven (AndroidX, Material) se píšou plným názvem třídy, například
<com.google.android.material.button.MaterialButton>.
| Jednotka | Použití |
|---|---|
| dp | rozměry a okraje; nezávislé na hustotě displeje (160 dp ≈ 1 palec) |
| sp | velikost písma; navíc respektuje nastavení velikosti písma v systému |
| match_parent | prvek zabere celý rozměr rodiče |
| wrap_content | prvek bude jen tak velký, jak potřebuje jeho obsah |
| 0dp (v ConstraintLayout) | velikost určí omezení (constraints) na obou stranách |
Tři jmenné prostory: android, app a tools
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/avatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/avatar_popis"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/jmeno"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/avatar"
tools:text="Jana Nováková" />
</androidx.constraintlayout.widget.ConstraintLayout> -
android:— atributy definované samotným Androidem. -
app:s URIhttp://schemas.android.com/apk/res-auto— atributy z knihoven a z vlastních komponent. Adresares-autoje zvláštní: nástroje sestavení ji při kompilaci nahradí balíčkem, ve kterém je atribut skutečně deklarovaný. -
tools:s URIhttp://schemas.android.com/tools— pokyny jen pro Android Studio.tools:textzobrazí ukázkový text v náhledu, ale do aplikace se nedostane.
Je to názorná ukázka, jak fungují jmenné prostory: atribut
text z prostoru android a text z prostoru
tools jsou pro parser dva různé atributy.
Odkazy na zdroje
Hodnoty se do layoutu většinou nepíšou natvrdo, ale odkazují na zdroje. Při sestavení z nich
vznikne třída R s číselnými identifikátory.
| Zápis | Význam |
|---|---|
| @+id/nadpis | vytvoří nový identifikátor prvku (v kódu R.id.nadpis) |
| @id/avatar | odkaz na už existující identifikátor |
| @string/vitejte | text z res/values/strings.xml |
| @dimen/mezera, @color/primarni | rozměr nebo barva z res/values |
| @drawable/ic_sipka | obrázek nebo vektor z res/drawable |
| @android:string/ok | zdroj ze systémového frameworku Androidu |
| ?attr/colorPrimary | hodnota atributu z aktuálního motivu (tématu) |
Texty a lokalizace
Texty jsou v res/values/strings.xml. Překlad je stejný soubor ve složce s
kvalifikátorem jazyka — pro češtinu values-cs. Android vybere složku podle jazyka
zařízení a chybějící texty doplní z výchozí složky:
<?xml version="1.0" encoding="utf-8"?>
<!-- res/values/strings.xml – výchozí (anglické) texty -->
<resources>
<string name="app_name">Shopping list</string>
<string name="vitejte">Welcome!</string>
<string name="pocet_polozek">%1$d items</string>
<string name="uvozovky">Don\'t forget the \"milk\"</string>
</resources> <?xml version="1.0" encoding="utf-8"?>
<!-- res/values-cs/strings.xml – použije se v češtině -->
<resources>
<string name="app_name">Nákupní seznam</string>
<string name="vitejte">Vítejte!</string>
<plurals name="polozky">
<item quantity="one">%d položka</item>
<item quantity="few">%d položky</item>
<item quantity="many">%d položky</item>
<item quantity="other">%d položek</item>
</plurals>
</resources> -
Kromě pravidel XML (
&,<) platí v textech i vlastní escapování Androidu: apostrof a uvozovky je potřeba zapsat jako\'a\", jinak sestavení skončí chybou. -
Čeština má víc tvarů množného čísla, proto používej
<plurals>místo skládání „položka/položky/položek“ v kódu. - Parametry ve formátovacích řetězcích čísluj (
%1$d,%2$s), aby je překlad mohl přeházet.
AndroidManifest.xml
Manifest popisuje aplikaci pro systém a obchod Google Play: které aktivity a služby obsahuje, která je vstupní (ikona v launcheru), jaká potřebuje oprávnění a jakou má ikonu a název.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.NakupniSeznam">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest> -
Název balíčku se dnes neuvádí atributem
packagev manifestu, ale jakonamespaceaapplicationIdv souborubuild.gradle. -
Od Androidu 12 musí mít každá aktivita, služba nebo přijímač s
<intent-filter>výslovně uvedený atributandroid:exported. - Výsledný manifest vzniká slučováním manifestů aplikace a všech knihoven. Co se nakonec dostalo do aplikace, ukáže v Android Studiu záložka Merged Manifest.
Vektorové ikony (vector drawable)
Android má vlastní vektorový formát, který se podobá SVG. Atribut pathData používá
stejnou syntaxi příkazů jako d v SVG, a Android Studio proto umí
SVG převést (Vector Asset Studio). Nepodporuje ale vše — filtry, CSS nebo vložené
rastry při převodu zmizí.
<!-- res/drawable/ic_sipka.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
</vector> Propojení s kódem
Layout se v aktivitě načte metodou setContentView. Místo hledání prvků přes
findViewById se dnes používá View Binding: pro každý layout se
vygeneruje třída s vlastnostmi pojmenovanými podle android:id
(pokracovat → binding.pokracovat).
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// res/layout/activity_main.xml -> třída ActivityMainBinding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.pokracovat.setOnClickListener {
binding.nadpis.text = resources.getQuantityString(R.plurals.polozky, 3, 3)
}
}
}
Hotová aplikace (APK, AAB) už XML neobsahuje jako text. Nástroj AAPT2 layouty i manifest při
sestavení převede do binárního XML, takže po rozbalení APK uvidíš nečitelná
data. Čitelnou podobu vrátí například apktool d aplikace.apk nebo
APK Analyzer v Android Studiu.