Modifier — is een onveranderlijk object in Jetpack Compose dat de eigenschappen van een UI-component bepaalt: grootte, marges, achtergrond, gebarenverwerking en gedrag. Modifiers worden samengevoegd in een keten door opeenvolgende aanroepen, waarbij de volgorde van toepassing het resultaat kritisch beïnvloedt. Volgens Google Android Developers, 2026 is correct gebruik van Modifier de basis voor het bouwen van een flexibele en performante interface in declaratieve UI.
Belangrijkste punten
Modifier — is een interface uit het pakket androidx.compose.ui die het Composite-patroon implementeert. Elke modifier is een element van de keten dat de vorige omhult en zijn eigen gedrag toevoegt. Modifier is onveranderlijk — elke wijziging creëert een nieuw object door kopiëren met toevoeging van een nieuw element aan de keten. Dit maakt het veilig delen van één Modifier tussen meerdere componenten mogelijk.
Basis modifier-functies worden aangeroepen via het companion-object Modifier (bijv. Modifier.padding(), Modifier.fillMaxWidth()). Elke functie retourneert een nieuwe Modifier met het toegevoegde element. Als er meerdere modifiers zijn, worden ze samengevoegd in een keten: Modifier.padding(16.dp).fillMaxWidth().background(Color.Blue). De volgorde is de richting van buiten naar binnen ten opzichte van het UI-element.
In tegenstelling tot traditionele Views, waar eigenschappen werden ingesteld via setters (view.setPadding(...), view.setBackground(...)), is Modifier in Compose een declaratieve beschrijving. De component past modifiers niet "toe" tijdens de uitvoering — LayoutNode doorloopt in de compositiefase de Modifier-keten en verzamelt er een lijst van Modifier.Element uit, die vervolgens worden verwerkt in de meet- en plaatsingsfase.
De volgorde van modifiers — een van de meest voorkomende fouten in Compose. Elke modifier omhult de vorige en bewerkingen worden van buiten naar binnen uitgevoerd. Bijvoorbeeld padding(16.dp).clickable { }: eerst wordt marge rond het element toegevoegd, vervolgens omvat het klikgebied ook de marge. clickable { }.padding(16.dp): eerst is het klikgebied gelijk aan de grootte van het element, daarna wordt marge eromheen toegevoegd — klikken op de marge werkt niet.
Onthoudregel: lees de keten van links naar rechts en pas toe van buiten naar binnen. De eerste modifier — de buitenste, wordt toegepast op het gebied rond het element. De laatste — de binnenste, wordt direct toegepast op de inhoud. Grootte-modifiers (size, fillMaxWidth) moeten na marges komen, als de marge nodig is van de ouder, of vóór marges, als de inhoud eerst moet worden beperkt en vervolgens gecentreerd.
Voorbeeld: size(100.dp).padding(10.dp) — element met vaste grootte 100dp, daarna padding 10dp aan de buitenkant (eindgrootte 120dp). padding(10.dp).size(100.dp) — padding 10dp vermindert de beschikbare ruimte tot (ouder - 20dp), daarna kan size(100dp) de ouder overschrijden. Denk altijd bewust na over de volgorde en gebruik weergavetests om het resultaat te verifiëren.
| Volgorde | Resultaat |
|---|---|
| padding → clickable | Klikken werkt ook op het margegebied |
| clickable → padding | Klikken werkt alleen op inhoud, marge is dode zone |
| size → padding | Element size(100), padding buiten → 100+2*pad |
| padding → size | padding vermindert ruimte, size kan buiten grenzen treden |
| background → padding | Achtergrond vult het hele element inclusief buitenste gebied |
| padding → background | Achtergrond alleen binnen de marge (buitenste gebied transparant) |
De standaard Compose-bibliotheek bevat ~50+ modifiers, verdeeld in categorieën. Grootte en positionering: Modifier.size(), width(), height(), fillMaxSize(), fillMaxWidth(), fillMaxHeight(), defaultMinSize(), requiredSize(). Marges en grenzen: padding(), offset(), margin (geplaatst via padding van ouder of Layout). Decoratie: background(), border(), clip(), alpha(), shadow(), blur().
Gedrag en gebaren: clickable(), combinedClickable(), pointerInput(), draggable(), swipeable(). Plaatsing in container: weight() (voor Row/Column), align(), alignBy(), matchParentSize(). Semantiek en toegankelijkheid: semantics(), testTag(), clearAndSetSemantics(). Tekenen: drawBehind(), drawWithContent(), drawModifier() — modifiers die aangepast tekenen op het canvas mogelijk maken.
Semantische modifiers — een bijzondere categorie. Modifier.semantics {} bepaalt hoe het element wordt weergegeven in de Accessibility-boom. Compose vult semantiek automatisch in uit tekst, maar voor aangepaste componenten moeten rollen, statussen en acties handmatig worden ingesteld. Dit is cruciaal voor WCAG 2.2-naleving en correcte werking van TalkBack (Android) en VoiceOver (iOS).
@Composable
fun ModifierDemo() {
// Modifier-keten met correcte volgorde
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("Raak me aan")
}
}
Modifier.composed — is een factory-methode die het mogelijk maakt samengestelde modifiers te creëren die andere modifiers, LocalComposition en lokale status kunnen gebruiken. In tegenstelling tot een gewone extensiefunctie, maakt composed elke keer een instantie bij toepassing, waardoor het een eigen status binnen de modifier kan hebben.
Wanneer composed te gebruiken: herhalende combinaties van modifiers (bijv. standaard kaartstijl: padding + background + border + clickable); modifiers met status (geanimeerde achtergrondverandering bij indrukken); toegang tot CompositionLocals (MaterialTheme-kleurschema, pixeldichtheid). In gewone gevallen is een gewone extensiefunctie zonder composed voldoende.
Prestaties van composed: elke aanroep maakt een nieuw modifier-object aan, wat kan leiden tot overbodige allocaties bij recompositie. Om dit te voorkomen, wikkel composed in remember. Google raadt aan composed alleen te gebruiken wanneer er echt status of CompositionLocal binnen nodig is. Voor statische combinaties gebruik je gewone extensiefuncties.
// Aangepaste modifier via composed met status
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))
}
// Gebruiksvoorbeeld
@Composable
fun CardList() {
Column {
Box(Modifier.cardStyle()) { Text("Item 1") }
Box(Modifier.cardStyle(isSelected = true)) { Text("Geselecteerd") }
}
}
// Statische versie (zonder composed) — sneller
fun Modifier.simpleCardStyle(): Modifier =
this.fillMaxWidth().padding(8.dp).clip(RoundedCornerShape(4.dp))
Vermijd het opnieuw aanmaken van Modifier bij elke recompositie. Als de modifier niet afhankelijk is van variabele gegevens — plaats hem dan in een constante of remember. Elke keer dat Modifier.padding().background() wordt aangeroepen, worden nieuwe Modifier.Element-objecten gemaakt. In een geïsoleerd component is dit onmerkbaar, maar in een LazyColumn met honderden elementen veroorzaken overbodige allocaties merkbare vertragingen bij het scrollen.
Regel: als de modifier-keten niet afhankelijk is van parameters van de Composable-functie — declareer deze dan als val buiten de functie (op bestandsniveau of in Companion). Als deze wel afhankelijk is — gebruik remember(afhankelijkheid) { ... }. Voor modifiers die altijd hetzelfde zijn, is val buiten Composable het meest efficiënt: dergelijke objecten worden eenmalig gemaakt voor de hele levensduur van de applicatie.
Beste praktijken voor Modifier-volgorde: plaats modifiers in logische volgorde: eerst grootte/marges (layout), dan decoratie (background, border), vervolgens gedrag (clickable, pointerInput). Dit verbetert niet alleen de leesbaarheid, maar helpt Compose Runtime ook de keten te optimaliseren in de meetfase. Vermijd ook overmatige geneste Box met verschillende Modifiers — vaak kan één Modifier op de bovenliggende container 2-3 geneste vervangen.
// ✅ Goed: constante buiten Composable
private val cardModifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(8.dp))
@Composable
fun CardContent() {
Box(cardModifier.background(Color.White)) { ... }
}
// ❌ Fout: opnieuw aanmaken bij elke recompositie
@Composable
fun BadCard() {
Box(Modifier.fillMaxWidth().padding(16.dp)) { ... }
}
// ✅ Goed: remember voor dynamische Modifier
@Composable
fun DynamicCard(color: Color) {
val modifier = remember(color) {
Modifier.fillMaxWidth().background(color)
}
Box(modifier) { ... }
}
Veelgestelde vragen
Ja, Modifier is onveranderlijk, dus één object kan veilig op meerdere plaatsen worden gebruikt. Als je echter een composed-modifier gebruikt, maakt elke aanroep een nieuwe instantie. Voor statische ketens is een constante of val buiten Composable de optimale oplossing.
Gebruik Layout Inspector in Android Studio — deze toont visueel de grenzen van elke Modifier. Voeg voor programmatische debugging Modifier.border() met verschillende kleuren toe bij elke stap van de keten om de toepassingsgrenzen van elke modifier te zien.
Modifier.then(other) voegt de keten other toe aan this. Opeenvolgende aanroep (Modifier.a().b()) is gelijk aan Modifier.then(a()).then(b()). Er is geen verschil — het is hetzelfde ketenmechanisme. then() is handig wanneer je een complete keten uit een variabele moet toevoegen.
Modifier.semantics {} bepaalt hoe het element wordt beschreven voor de schermlezer. Modifier.clickable() voegt automatisch de rol Button en Action(OnClick) toe. Voor aangepaste gebaren moet je semantics expliciet specificeren. Zonder semantische modifiers kunnen TalkBack-gebruikers niet interageren met aangepaste componenten.
Modifier.background(color, shape) werkt met hoeken, maar clip() moet VOOR background komen om de hoeken bij te snijden. De juiste volgorde: clip(shape).background(color). Als je ook de inhoud binnenin moet bijsnijden, gebruik dan clipToBounds() op de ouder.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook