Modifier — egy megváltoztathatatlan objektum a Jetpack Compose-ban, amely meghatározza a UI-komponens tulajdonságait: méret, margók, háttér, gesztusok feldolgozása és viselkedés. A módosítók egy láncba egyesülnek szekvenciális hívással, és alkalmazásuk sorrendje kritikusan befolyásolja az eredményt. A Google Android Developers, 2026 szerint a Modifier helyes használata a rugalmas és hatékony felület építésének alapja a deklaratív UI-ban.
Főbb pontok
Modifier — egy interfész az androidx.compose.ui csomagból, amely a Composite mintát implementálja. Minden módosító a lánc egy eleme, amely becsomagolja az előzőt és hozzáadja saját viselkedését. A Modifier megváltoztathatatlan — bármilyen változtatás új objektumot hoz létre másolással, egy új elem hozzáadásával a lánchoz. Ez lehetővé teszi egy Modifier biztonságos megosztását több komponens között.
Az alapvető módosító-függvények a Modifier társobjektumon keresztül hívhatók (pl. Modifier.padding(), Modifier.fillMaxWidth()). Minden függvény egy új Modifier-t ad vissza a hozzáadott elemmel. Ha több módosító van, egy láncba egyesülnek: Modifier.padding(16.dp).fillMaxWidth().background(Color.Blue). A sorrend a kívülről befelé irány a UI-elemhez képest.
A hagyományos View-okkal ellentétben, ahol a tulajdonságokat settereken keresztül állították be (view.setPadding(...), view.setBackground(...)), a Compose-ban a Modifier egy deklaratív leírás. A komponens nem "alkalmazza" a módosítókat futás közben — a LayoutNode a kompozíciós fázisban végigmegy a Modifier láncon és összegyűjti belőle a Modifier.Element listát, amelyeket aztán a mérési és elrendezési fázisban dolgoz fel.
A módosítók sorrendje — az egyik leggyakoribb hiba a Compose-ban. Minden módosító becsomagolja az előzőt, és a műveletek kívülről befelé hajtódnak végre. Például padding(16.dp).clickable { }: először margó kerül az elem köré, majd a kattintási terület a margót is tartalmazza. clickable { }.padding(16.dp): először a kattintási terület egyenlő az elem méretével, majd margó kerül köré — a margóra kattintás nem működik.
Megjegyzendő szabály: olvassa a láncot balról jobbra és alkalmazza kívülről befelé. Az első módosító — a legkülső, az elem körüli területre alkalmazandó. Az utolsó — a legbelső, közvetlenül a tartalomra alkalmazandó. A méret módosítók (size, fillMaxWidth) a margók után következzenek, ha a margó a szülőtől szükséges, vagy a margók előtt, ha a tartalmat először korlátozni kell, majd középre igazítani.
Példa: size(100.dp).padding(10.dp) — rögzített méretű elem 100dp, majd padding 10dp kívül (végső méret 120dp). padding(10.dp).size(100.dp) — padding 10dp csökkenti a rendelkezésre álló helyet (szülő - 20dp), majd size(100dp) túllépheti a szülőt. Mindig tudatosan gondolja át a sorrendet, használva megjelenítési teszteket az eredmény ellenőrzéséhez.
| Sorrend | Eredmény |
|---|---|
| padding → clickable | A kattintás a margó területén is működik |
| clickable → padding | A kattintás csak a tartalmon működik, a margó holt zóna |
| size → padding | Elem size(100), padding kívül → 100+2*pad |
| padding → size | padding csökkenti a helyet, size túllépheti a határokat |
| background → padding | A háttér kitölti az egész elemet, beleértve a külső területet |
| padding → background | A háttér csak a margón belül (a külső terület átlátszó) |
A standard Compose könyvtár ~50+ módosítót tartalmaz, kategóriákra bontva. Méret és pozicionálás: Modifier.size(), width(), height(), fillMaxSize(), fillMaxWidth(), fillMaxHeight(), defaultMinSize(), requiredSize(). Margók és határok: padding(), offset(), margin (a szülő padding-jén vagy Layout-on keresztül elhelyezve). Dekoráció: background(), border(), clip(), alpha(), shadow(), blur().
Viselkedés és gesztusok: clickable(), combinedClickable(), pointerInput(), draggable(), swipeable(). Elhelyezés a konténerben: weight() (Row/Column esetén), align(), alignBy(), matchParentSize(). Szemantika és hozzáférhetőség: semantics(), testTag(), clearAndSetSemantics(). Rajzolás: drawBehind(), drawWithContent(), drawModifier() — módosítók, amelyek egyedi rajzolást tesznek lehetővé a vásznon.
Szemantikus módosítók — egy különleges kategória. A Modifier.semantics {} meghatározza, hogy az elem hogyan jelenjen meg az Accessibility fában. A Compose automatikusan kitölti a szemantikát a szövegből, de az egyedi komponensekhez manuálisan kell megadni a szerepköröket, állapotokat és műveleteket. Ez kritikus a WCAG 2.2-nek való megfeleléshez és a TalkBack (Android) és VoiceOver (iOS) helyes működéséhez.
@Composable
fun ModifierDemo() {
// Módosítói lánc helyes sorrenddel
Box(
modifier = Modifier
.size(150.dp)
.padding(8.dp)
.border(2.dp, Color.Gray)
.background(Color(0xFFE3F2FD))
.clickable { /* handle click */ }
.semantics {
contentDescription = "Demo card with click action"
role = Role.Button
}
) {
Text("Érints meg")
}
}
Modifier.composed — egy gyári metódus, amely lehetővé teszi összetett módosítók létrehozását, amelyek használhatnak más módosítókat, LocalComposition-t és lokális állapotot. Ellentétben a szokásos kiterjesztő függvénnyel, a composed minden alkalmazáskor létrehoz egy példányt, ami lehetővé teszi, hogy saját állapota legyen a módosítón belül.
Mikor használjuk a composed-t: ismétlődő kombinációk (pl. standard kártya stílus: padding + background + border + clickable); állapottal rendelkező módosítók (animált háttérváltás nyomásra); hozzáférés a CompositionLocals-hoz (MaterialTheme színséma, pixelsűrűség). Hétköznapi esetekben egy szokásos kiterjesztő függvény composed nélkül is elegendő.
A composed teljesítménye: minden hívás új módosító objektumot hoz létre, ami felesleges foglalásokhoz vezethet rekompozíciónál. Ennek megelőzésére csomagolja a composed-t remember-be. A Google azt ajánlja, hogy csak akkor használja a composed-t, ha ténylegesen szükség van állapotra vagy CompositionLocal-ra belül. Statikus kombinációkhoz használjon szokásos kiterjesztő függvényeket.
// Egyedi módosító composed segítségével állapottal
fun Modifier.cardStyle(
elevation: Dp = 4.dp,
isSelected: Boolean = false
): Modifier = this.composed {
val backgroundColor = if (isSelected)
MaterialTheme.colorScheme.primaryContainer
else
MaterialTheme.colorScheme.surface
this
.fillMaxWidth()
.padding(12.dp)
.background(backgroundColor, RoundedCornerShape(8.dp))
.shadow(elevation, RoundedCornerShape(8.dp))
}
// Használati példa
@Composable
fun CardList() {
Column {
Box(Modifier.cardStyle()) { Text("1. elem") }
Box(Modifier.cardStyle(isSelected = true)) { Text("Kiválasztva") }
}
}
// Statikus verzió (composed nélkül) — gyorsabb
fun Modifier.simpleCardStyle(): Modifier =
this.fillMaxWidth().padding(8.dp).clip(RoundedCornerShape(4.dp))
Kerülje a Modifier újralétrehozását minden rekompozíciónál. Ha a módosító nem függ változó adatoktól — tegye ki egy konstansba vagy remember-be. Minden alkalommal, amikor Modifier.padding().background() hívódik, új Modifier.Element objektumok jönnek létre. Egy elkülönített komponensben ez észrevehetetlen, de egy LazyColumn-ban több száz elemmel a felesleges foglalások észrevehető lassulást okoznak görgetéskor.
Szabály: ha a módosítói lánc nem függ a Composable függvény paramétereitől — deklarálja val-ként a függvényen kívül (fájl szinten vagy Companion-ban). Ha függ — használjon remember(függőség) { ... }-t. Azokhoz a módosítókhoz, amelyek mindig ugyanazok, a leghatékonyabb a val a Composable-en kívül: az ilyen objektumok egyszer jönnek létre az alkalmazás teljes élettartama alatt.
Modifier sorrend legjobb gyakorlatok: helyezze a módosítókat logikus sorrendbe: először méret/margók (layout), aztán dekoráció (background, border), majd viselkedés (clickable, pointerInput). Ez nemcsak az olvashatóságot javítja, hanem segíti a Compose Runtime-ot a lánc optimalizálásában a mérési fázisban. Kerülje a túlzottan egymásba ágyazott Box-okat különböző Modifier-ekkel — gyakran egyetlen Modifier a szülő konténeren helyettesíthet 2-3 egymásba ágyazottat.
// ✅ Jó: konstans a Composable-en kívül
private val cardModifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(8.dp))
@Composable
fun CardContent() {
Box(cardModifier.background(Color.White)) { ... }
}
// ❌ Rossz: újralétrehozás minden rekompozíciónál
@Composable
fun BadCard() {
Box(Modifier.fillMaxWidth().padding(16.dp)) { ... }
}
// ✅ Jó: remember dinamikus Modifier-hez
@Composable
fun DynamicCard(color: Color) {
val modifier = remember(color) {
Modifier.fillMaxWidth().background(color)
}
Box(modifier) { ... }
}
Gyakran Ismételt Kérdések
Igen, a Modifier megváltoztathatatlan, így egy objektum biztonságosan használható több helyen. Ha azonban composed-módosítót használ, minden hívás új példányt hoz létre. Statikus láncokhoz konstans vagy val a Composable-en kívül az optimális megoldás.
Használja a Layout Inspector-t az Android Studio-ban — vizuálisan megjeleníti az egyes Modifier-ek határait. Programozott hibakereséshez adjon hozzá Modifier.border()-t különböző színekkel a lánc minden lépésénél, hogy lássa az egyes módosítók alkalmazási határait.
Modifier.then(other) hozzáfűzi az other láncot a this-hez. A szekvenciális hívás (Modifier.a().b()) egyenértékű a Modifier.then(a()).then(b()) hívással. Nincs különbség — ez ugyanaz a lánc mechanizmus. A then() akkor hasznos, ha egy kész láncot kell hozzáfűzni egy változóból.
A Modifier.semantics {} meghatározza, hogy az elem hogyan legyen leírva a képernyőolvasó számára. A Modifier.clickable() automatikusan hozzáadja a Button szerepkört és az Action(OnClick) műveletet. Egyedi gesztusokhoz explicit módon meg kell adni a semantics-t. Szemantikus módosítók nélkül a TalkBack felhasználók nem tudnak interakcióba lépni az egyedi komponensekkel.
Modifier.background(color, shape) működik a sarkokkal, de a clip()-nek a background ELŐTT kell lennie a sarkok levágásához. A helyes sorrend: clip(shape).background(color). Ha a belső tartalmat is le kell vágni, használja a clipToBounds()-t a szülőn.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is