Jetpack Compose je predurčený pre tvorbu UI na platforme Android.
Využitie API Jetpack Compose pre Multiplatform popisuje článok: Compose Multiplatform
Jetpack Compose je nástroj z produkcie Google. Používa sa pre tvorbu UI (GUI). Zároveň nahrádza pôvodnu deklaráciu formulárov a komponentov pôvodným XML definičnými súbormi za deklaratívne progromavanie, teda všetko je v jednom súbore a pomôcka je online zobrazovanie pri programovaní pomocou anotácie @Preview.
Postup tvorenia kódu je jednoduchý. Vzhľad používateľského rozhrania zobrazovaného na displeji sa postupne skladá z existujúcich, alebo vlastných komponentov. Vlastné komponenty taktiež prijímajú stavy a vysielajú udalosti pomocou Live dát, ktoré využívajú dátové modely. Coroutines následne umožňujú reťaziť zobrazenia a vstupy v krátkom kóde.
Komplexnosť komponentov ho predurčuje pre tvorbu Multiplatform aplikácií pre Android, iOS, desktop, web (export projektu do Xcode, JVM, JavaScript).
Príklad komponentov nástroja Jetpack Compose: tlačítka, textové polia a iné z Material Design 3. Jetpack Compose vyniká jednoduchosťou a dynamikou písaného kódu, rešpektuje modely dynamických dát, združuje kódy pod jeden jazyk - Kotlin a integruje pokročilé technológie: Room (DB), Hilt (vstrekovanie dát) a iné.
developer.android : Ako začať s Jetpack Compose
Príklad kódu, kde UI je v bloku setContent() :
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text(text = "Hello World!") } }
Základné štrukturovanie kompozície je prvkami:
Modifikátory umožňujú nastaviť rozmery, zarovnanie, odsadenie, interakcie a iné…
Kompletná škála komponentov je na developer.android
Zobrazí objekty pod sebou. Anotácia @Preview zabezpečí náhľad pre funkciu, ktorá by namala prijímať argumenty (okrem modifier) a odovzdávať hodnoty.
@Preview @Composable fun ColumnTest() { Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth().background(Color.Cyan) ) { Text(text = "Hello") Text(text = "Android") } }
Zobrazí objekty vedľa seba. Jednotka dp určuje veľkosť ktorá je nezávislá na hustote pizelov, sp sa škáluje na základe veľkosti textu zariadenia.
@Preview @Composable fun RowTest() { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().height(150.dp).background(Color.Cyan) ) { Text(text = "Hello") Text(text = "Android") } }
Container pre ďalšie komponenty (Row(), …)
Card(modifier = modifier, colors = ...) { Row(...) { Icon(...) Column(...) { .. } } }
Link na developers je hore pod nadpisom… ↑
Icon() - obrázokBox() {} - kontajner pre iné komponentyButton() {} - tlačítko s kontajneromTextButton() {} - tlačítko s kontajneromLazyColumn() {} - kontajner pre viditeľný zoznam položiekitem {} - definicia položiek pre LazyColumn()OutlinedTextField() - orámovanie s menovkouOutlinedButton(onclick = {…}, …) {} - tlačítko s container pre TEXT() a inéCheckbox() - zaškrtnutie voľbyScaffold() - kontajner
Jedná sa o designový jazyk. Tu je použitý Material Design 3 (M3). V základe pre aplikáciu používame primárnu a sekundárn farbu - primárna farba je výraznejšia a použije sa pre hlavný prvok. Popis napríklad tlačítok používa aj on farby (v Theme.kt). Typologické pravidlá predpokladajú čo najmenšiu škálu použitých fontov. Pre výber vhodných fontov je možné využiť Google Fonts. Pre zaoblené hrany komponentov sa využije Modifier.
Definície sú v: …/ui/theme/[Theme.kt, Color.kt, Type.kt]
Aplikovanie témy na kód:
@Preview @Composable fun ColoredButton() { MyApkMaterialTheme { Button( onClick = { /*TODO*/ }, modifier = Modifier.clip(CutCornerShape(16.dp)), colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colors.primary) ) { Text( text = "Tlačítko", color = MaterialTheme.colors.onPrimary, modifier = Modifier.background(MaterialTheme.colors.primary) ) } } }
Je akákoľvek hodnota, ktorá sa mení v čase, napríklad texty v textových komponentoch, dáta či anymácie. Stav v Compose sa ukladá príkazom remember, napríklad (takmer identické vyjadrenia):
val mutableState = remember { mutableStateOf(value) } // i preferred var value by remember { mutableStateOf(value) } val (value, setValue) = remember { mutableStateOf(value) }
┌──────────────────────────────────┐
│ Komponenta so stavom │
└──────────────────────────────────┘
⬇ ⬆
Stav Udalosti
⬇ ⬆
┌──────────────────────────────────┐
│ Komponenta vytvárajúca rozhranie │
└──────────────────────────────────┘
val status = mutableState.value,
príklad získania stavu v textovej komponente:
OutlinedTextField( value = mutableState.value, label = { Text("your number") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), onValueChange = { newInput -> mutableState.value = newInput } )
príklad onClick v tlačidle:
fun OperationButton(modifier: Modifier = Modifier, text: String, onClick: () -> Unit = {}) { Button( onClick = { onClick() }, colors = ButtonDefaults.buttonColors(MaterialTheme.colors.secondary), modifier = modifier ) ... }
Model-View-ViewModel je koncept pre udržateľné a škálovateľné (rôzne zdroje dát) aplikácie. Model oddeľuje používateľské rozhranie (GUI), dáta a iné komponenty. MVVM sa špecializuje na Android (inde je to MVC a podobne). Vrstvy MVVM architektúry:
┌──────┐ ┌───────────┐ ┌───────┐ │ View │◄-►│ ViewModel │◄-►│ Model │ └──────┘ └───────────┘ └───────┘ Compose Room
Umožňuje používať anotácie pre metódy a vlastnosti SQL databáz.
Modul kapt je už nepraktický, namiesto neho sa používa ksp. Knižnica Room, ktorá funguje s oboma modelmi. Pri potrebe použiť ksp odporúčam dohľadať príklady pre zápisy do: build.gradle.kts (prj) a build.gradle.kts (:app).
Link na migráciu z kapt na ksp: https://developer.android.com/build/migrate-to-ksp
Umožňuje používať anotácie pre metódy a vlastnosti SQL databáz.
aj napriek dostupným návodom s popisom manuálneho doplnenia buid súborov som testol možnosti správy modulov v projekte (AS) a funguje to spoľahlivo, nakoľko ponúka aktuálne knižnice, Teda zhruba tieto moduly treba nájsť a aplikovať:
ďalej upraviť:
verzia musí byť zhodná s verziou Kotlin (v libs.version.toml)
plugins { ... id("com.google.devtools.ksp") version "2.2.0-2.0.2" apply false }
plugins { ... id("com.google.devtools.ksp") } compileOptions { // 17 is minimum sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } dependencies { ... ksp(libs.androidx.room.compiler.v272) }
následne až v kóde budú použité metódy Room, tak potvrdiť import: @Entity ⇒ import room.common ⇒ build.gradle.kts(:app)
zárovaň sa upravuje automaticky aj blok dependencies {…} v build.gradle.kts(:app) a aj libs.versions.toml (kde občas treba potvriť vyššie verzie knižníc)
Je určená pre prácu s SQLite Android. Prevádza riadky na objekty a naopak. Základné komponenty knižnice:
Príklad použitia knižnice Room:
import androidx.room.Entity import androidx.room.PrimaryKey /** 1. define data object and make entity : data/MyData.kt */ @Entity data class MyData( @PrimaryKey(autoGenerate = true) val recordId: Long? = null, // primary key val name: String ) // ... any functions for operations with entity /** 2. interface : data/MyDataDao.kt */ @Dao interface MyDataDao { @Query("SELECT * FROM MyData") fun getAll(): Flow<List<MyData>> // Flow: see coroutines @Insert fun insert(myData: MyData) @Update fun update(myData: MyData) @Delete fun delete(myData: MyData) } /** 3. class of database : data/AppDatabase.kt */ @Database(entities = [MyData::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun myDataDao(): MyDataDao } /** 4. instance for all project : service/ServiceLocator.kt */ object ServiceLocator { private var _myDataDao: MyDataDao? = null val myDataDao: MyDataDao? get() = _myDataDao fun setMyDataDao(myDataDao: MyDataDao) { _myDataDao = myDataDao } } /** 5. application class : application/ExampleApplication.kt - need edit AndroidManifest.xml -> <application ... android:name=".application.ExampleApplication" ... </application> */ class ExampleApplication : Application() { override fun onCreate() { super.onCreate() val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "myData-database" ).build() ServiceLocator.setMyDataDao(db.myDataDao()) } }
Následne treba vytvoriť ViewModel, ktorý prepojí prezentačnú vrstvu s dátovou vrstvou (modelom), čím bude idea MVVM naplnená. Mal by obsahovať metódy nad dátami (získanie, vloženie, úpravu a mazanie) pomocou metód z rozhrania DAO.
Metódy nad dátami je vhodné realizovať v bloku init {…} pomocou coroutines: viewModelScope.launch {…} a uložiť do kolekcie(í).
Postupy pre zmeny odporúča Material Design 3. Základný princíp je použitie Primárnych a Sekundárnych farieb, ako pre svetlý, tak i pre tmavý režim zobrazenia.
Samotná deklarácia faireb je v ui/theme/Color.kt.
Generovanie farieb môže zabezpečiť aj Figma - Material Theme Builder, alebo Material Theme Builder na GitHub.
Samotná deklarácia tém je v ui/theme/Theme.kt.
Ďalšie fonty je možné získať na adrese Google
Pre ich použitie je treba stiahnuť zip a vytvoriť v AS: app → new Android Resource Directory : font/font a doňho nakopírovať vybrané zo stiahnutého zip-u.
Samotná deklarácia tém je v ui/theme/Type.kt.