Modifier — ay isang hindi nababagong bagay sa Jetpack Compose na tumutukoy sa mga katangian ng UI component: laki, margin, background, pagproseso ng kilos, at pag-uugali. Ang mga modifier ay pinagsama sa isang chain sa pamamagitan ng sunod-sunod na pagtawag, kung saan ang pagkakasunod-sunod ng paglalapat ay kritikal na nakakaapekto sa resulta. Ayon sa Google Android Developers, 2026, ang tamang paggamit ng Modifier ay pundasyon ng pagbuo ng flexible at mahusay na interface sa declarative UI.
Mga Pangunahing Punto
Modifier — ay isang interface mula sa package na androidx.compose.ui na nagpapatupad ng Composite pattern. Ang bawat modifier ay isang elemento ng chain na bumabalot sa nauna at nagdaragdag ng sarili nitong pag-uugali. Ang Modifier ay hindi nababago — anumang pagbabago ay lumilikha ng bagong bagay sa pamamagitan ng pagkopya kasama ang pagdaragdag ng bagong elemento sa chain. Ito ay nagpapahintulot ng ligtas na pagbabahagi ng isang Modifier sa maraming component.
Ang mga pangunahing function-modifier ay tinatawag sa pamamagitan ng companion object na Modifier (hal., Modifier.padding(), Modifier.fillMaxWidth()). Ang bawat function ay nagbabalik ng bagong Modifier na may idinagdag na elemento. Kung maraming modifier, pinagsama sila sa isang chain: Modifier.padding(16.dp).fillMaxWidth().background(Color.Blue). Ang pagkakasunod-sunod ay direksyon mula sa labas patungo sa loob kaugnay ng UI element.
Hindi tulad ng tradisyonal na View, kung saan ang mga katangian ay itinakda sa pamamagitan ng setters (view.setPadding(...), view.setBackground(...)), sa Compose Modifier ay isang declarative na paglalarawan. Ang component ay hindi "naglalapat" ng mga modifier sa panahon ng pagpapatupad — ang LayoutNode sa phase ng komposisyon ay dumadaan sa Modifier chain at nangongolekta ng listahan ng Modifier.Element, na pagkatapos ay pinoproseso sa phase ng pagsukat at pag-aayos.
Ang pagkakasunod-sunod ng mga modifier — isa sa mga pinakakaraniwang pagkakamali sa Compose. Bawat modifier ay bumabalot sa nauna, at ang mga operasyon ay isinasagawa mula sa labas patungo sa loob. Halimbawa, padding(16.dp).clickable { }: unang idinagdag ang margin sa paligid ng elemento, pagkatapos ang lugar ng pag-click ay kasama rin ang margin. clickable { }.padding(16.dp): una ang lugar ng pag-click ay katumbas ng laki ng elemento, pagkatapos ang margin ay idinagdag sa paligid — ang pag-click sa margin ay hindi gagana.
Panuntunan sa pag-alala: basahin ang chain mula kaliwa pakanan at ilapat mula sa labas patungo sa loob. Ang unang modifier — ang pinakalabas, inilalapat sa lugar sa paligid ng elemento. Ang huli — ang pinakaloob, direktang inilalapat sa nilalaman. Ang mga modifier ng laki (size, fillMaxWidth) ay dapat sumunod sa margin, kung ang margin ay kinakailangan mula sa magulang, o bago ang margin, kung ang nilalaman ay dapat munang limitahan, pagkatapos ay i-center.
Halimbawa: size(100.dp).padding(10.dp) — elemento ng nakapirming laki na 100dp, pagkatapos padding 10dp sa labas (huling laki 120dp). padding(10.dp).size(100.dp) — padding 10dp ay nagbawas ng available na espasyo sa (magulang - 20dp), pagkatapos size(100dp) ay maaaring lumampas sa magulang. Palaging pag-isipan ang pagkakasunod-sunod nang may kamalayan, gamit ang mga display test upang mapatunayan ang resulta.
| Pagkakasunod-sunod | Resulta |
|---|---|
| padding → clickable | Gumagana ang pag-click sa lugar ng margin din |
| clickable → padding | Gumagana lang ang pag-click sa nilalaman, margin ay patay na sona |
| size → padding | Elemento size(100), padding sa labas → 100+2*pad |
| padding → size | padding nagbawas ng espasyo, size maaaring lumampas sa hangganan |
| background → padding | Background pumupuno sa buong elemento kasama ang panlabas na lugar |
| padding → background | Background lamang sa loob ng margin (panlabas na lugar transparent) |
Ang standard na Compose library ay may kasamang ~50+ modifier, nahahati sa mga kategorya. Laki at pagpoposisyon: Modifier.size(), width(), height(), fillMaxSize(), fillMaxWidth(), fillMaxHeight(), defaultMinSize(), requiredSize(). Margin at hangganan: padding(), offset(), margin (inilalagay sa pamamagitan ng padding ng magulang o Layout). Dekorasyon: background(), border(), clip(), alpha(), shadow(), blur().
Pag-uugali at kilos: clickable(), combinedClickable(), pointerInput(), draggable(), swipeable(). Pag-aayos sa container: weight() (para sa Row/Column), align(), alignBy(), matchParentSize(). Semantika at accessibility: semantics(), testTag(), clearAndSetSemantics(). Pagguhit: drawBehind(), drawWithContent(), drawModifier() — mga modifier na nagbibigay-daan sa custom na pagguhit sa canvas.
Semantic modifier — isang espesyal na kategorya. Ang Modifier.semantics {} ay tumutukoy kung paano ire-represent ang elemento sa Accessibility tree. Awtomatikong pinupunan ng Compose ang semantika mula sa teksto, ngunit para sa custom na component, kailangang manu-manong itakda ang mga tungkulin, estado, at aksyon. Ito ay kritikal para sa pagsunod sa WCAG 2.2 at tamang paggana ng TalkBack (Android) at VoiceOver (iOS).
@Composable
fun ModifierDemo() {
// Chain ng modifier na may tamang pagkakasunod-sunod
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("Pindutin mo ako")
}
}
Modifier.composed — ay isang factory method na nagbibigay-daan sa paglikha ng mga composite modifier na maaaring gumamit ng iba pang modifier, LocalComposition, at lokal na estado. Hindi tulad ng ordinaryong extension function, ang composed ay gumagawa ng instance sa bawat paglalapat, na nagpapahintulot na magkaroon ng sariling estado sa loob ng modifier.
Kailan gagamitin ang composed: paulit-ulit na kumbinasyon ng mga modifier (hal., standard card style: padding + background + border + clickable); modifier na may estado (animated na pagbabago ng background kapag pinindot); access sa CompositionLocals (MaterialTheme color scheme, pixel density). Sa ordinaryong kaso, sapat na ang ordinaryong extension function na walang composed.
Pagganap ng composed: bawat tawag ay gumagawa ng bagong modifier object, na maaaring humantong sa labis na alokasyon sa recomposition. Upang maiwasan ito, balutin ang composed sa remember. Inirerekomenda ng Google ang paggamit ng composed lamang kapag talagang kailangan ang estado o CompositionLocal sa loob. Para sa static na kumbinasyon, gumamit ng ordinaryong extension function.
// Custom na modifier sa pamamagitan ng composed na may estado
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))
}
// Halimbawa ng paggamit
@Composable
fun CardList() {
Column {
Box(Modifier.cardStyle()) { Text("Item 1") }
Box(Modifier.cardStyle(isSelected = true)) { Text("Napili") }
}
}
// Static na bersyon (walang composed) — mas mabilis
fun Modifier.simpleCardStyle(): Modifier =
this.fillMaxWidth().padding(8.dp).clip(RoundedCornerShape(4.dp))
Iwasan ang muling paggawa ng Modifier sa bawat recomposition. Kung ang modifier ay hindi nakadepende sa nagbabagong data — ilagay ito sa isang constant o remember. Sa bawat pagtawag ng Modifier.padding().background() ay gumagawa ng bagong Modifier.Element object. Sa isang isolated component, ito ay hindi napapansin, ngunit sa LazyColumn na may daan-daang elemento, ang labis na alokasyon ay nagdudulot ng kapansin-pansing pagbagal sa pag-scroll.
Panuntunan: kung ang chain ng modifier ay hindi nakadepende sa mga parameter ng Composable function — ideklara ito bilang val sa labas ng function (sa antas ng file o Companion). Kung nakadepende — gumamit ng remember(dependency) { ... }. Para sa mga modifier na laging pareho, ang pinakamabisang paraan ay val sa labas ng Composable: ang mga ganitong bagay ay ginagawa nang isang beses para sa buong buhay ng application.
Pinakamahuhusay na kasanayan sa pag-order ng Modifier: ilagay ang mga modifier sa lohikal na pagkakasunod-sunod: una laki/margin (layout), pagkatapos dekorasyon (background, border), pagkatapos pag-uugali (clickable, pointerInput). Ito ay hindi lamang nagpapabuti ng pagiging madaling mabasa, ngunit tumutulong din sa Compose Runtime na i-optimize ang chain sa phase ng pagsukat. Iwasan din ang labis na nested Box na may iba't ibang Modifier — madalas ang isang Modifier sa parent container ay maaaring pumalit sa 2-3 nested.
// ✅ Mabuti: constant sa labas ng Composable
private val cardModifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(8.dp))
@Composable
fun CardContent() {
Box(cardModifier.background(Color.White)) { ... }
}
// ❌ Masama: muling paggawa sa bawat recomposition
@Composable
fun BadCard() {
Box(Modifier.fillMaxWidth().padding(16.dp)) { ... }
}
// ✅ Mabuti: remember para sa dynamic na Modifier
@Composable
fun DynamicCard(color: Color) {
val modifier = remember(color) {
Modifier.fillMaxWidth().background(color)
}
Box(modifier) { ... }
}
Mga Madalas Itanong
Oo, ang Modifier ay hindi nababago, kaya ang isang bagay ay maaaring ligtas na gamitin sa maraming lugar. Gayunpaman, kung gumagamit ka ng composed-modifier, bawat tawag ay gumagawa ng bagong instance. Para sa static na chain, ang constant o val sa labas ng Composable ay ang optimal na solusyon.
Gamitin ang Layout Inspector sa Android Studio — ito ay biswal na nagpapakita ng mga hangganan ng bawat Modifier. Para sa programmatic debugging, magdagdag ng Modifier.border() na may iba't ibang kulay sa bawat hakbang ng chain upang makita ang mga hangganan ng paglalapat ng bawat modifier.
Modifier.then(other) ay nagdurugtong ng chain other sa this. Ang sunod-sunod na pagtawag (Modifier.a().b()) ay katumbas ng Modifier.then(a()).then(b()). Walang pagkakaiba — ito ay parehong mekanismo ng chain. Ang then() ay kapaki-pakinabang kapag kailangan mong durugtungan ang isang handa nang chain mula sa isang variable.
Ang Modifier.semantics {} ay tumutukoy kung paano ilalarawan ang elemento para sa screen reader. Ang Modifier.clickable() ay awtomatikong nagdaragdag ng role na Button at Action(OnClick). Para sa custom na kilos, kailangan mong tukuyin nang tahasan ang semantics. Kung walang semantic modifier, ang mga gumagamit ng TalkBack ay hindi makikipag-ugnayan sa custom na component.
Modifier.background(color, shape) ay gumagana sa mga sulok, ngunit ang clip() ay dapat NASA UNA ng background upang maputol ang mga sulok. Ang tamang pagkakasunod-sunod: clip(shape).background(color). Kung kailangan mong putulin din ang nilalaman sa loob, gamitin ang clipToBounds() sa magulang.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din