@Composable: ano ito, anotasyon ng Compose at saklaw ng aplikasyon

May-akda: IT Sectr Nai-publish: 2026-06-27 Oras ng pagbabasa: 8 min

Ang anotasyong @Composable — pangunahing elemento ng Jetpack Compose na nagpapalit ng ordinaryong Kotlin function sa isang deklaratibong bloke ng gusali ng user interface. Kung wala ang anotasyong ito, walang screen na malilikha sa makabagong pag-develop ng Android. Ayon sa Google Android Developers, 2026, mahigit 80% ng mga bagong proyekto sa Kotlin ay gumagamit ng Compose para sa pagbuo ng UI, at ang @Composable ay ang pinakamadalas gamitin na anotasyon sa ecosystem.

Mga Pangunahing

  • @Composable — anotasyon ng Kotlin na nagpapahintulot sa function na ilarawan ang UI nang deklaratibo
  • Composable function ay maaari lamang tumawag sa iba pang Composable function, sumusunod sa konteksto ng komposisyon
  • Pag-restart ng Composable function ay nangyayari kapag nagbago ang input parameter o estado
  • Pagkakasunod-sunod ng tawag ng Composable function ay hindi garantisado — Ino-optimize ng Compose ang muling pagbuo ng UI
  • Pagpapangalan ng Composable function ay sumusunod sa PascalCase rule, tulad ng lahat ng component sa Compose

Ano ang @Composable sa Jetpack Compose

@Composable — ay isang anotasyon ng wikang Kotlin na nagmamarka ng function bilang inilaan para sa paglalarawan ng user interface sa framework ng Jetpack Compose. Kapag nakatagpo ng Kotlin compiler ang anotasyong ito, bumubuo ito ng karagdagang code na nagpapahintulot sa function na gumana sa konteksto ng komposisyon — ang sistema ng pamamahala ng UI tree.

Ang anotasyong @Composable ay ipinakilala ng Google noong 2021 kasama ang unang stable na bersyon ng Jetpack Compose 1.0. Bago ito lumabas, ang pag-develop ng interface para sa Android ay eksklusibong ginagawa sa pamamagitan ng XML markup at View system. Radikal na binago ng @Composable ang approach: sa halip na ilarawan ang UI sa isang hiwalay na markup file, isinusulat ng programmer ang interface nang direkta sa Kotlin.

Ang pangunahing pagkakaiba sa pagitan ng @Composable at ordinaryong Kotlin function — kakayahang magbasa at tumugon sa mga pagbabago ng estado. Kapag ang variable na binabasa ng Composable function ay nagbago ng halaga, awtomatikong nag-iiskedyul ang system ng pag-restart (recomposition) ng function na iyon. Ito ay nagpapalaya sa programmer mula sa manu-manong pag-update ng UI sa pamamagitan ng findViewById at setText.

Ang panloob na mekanika ng @Composable ay batay sa konsepto ng slot — isang espesyal na lugar ng memorya na inilalaan para sa bawat function sa loob ng komposisyon. Sa slot na ito ay nakaimbak ang mga value na ipinasa sa function, pati na rin ang impormasyon ng serbisyo na kinakailangan para sa paghahambing sa mga susunod na tawag.

Paano magdeklara ng Composable function

Upang magdeklara ng Composable function, sapat na ang magdagdag ng anotasyong @Composable bago ang keyword na fun. Ang function ay dapat nasa isang package na nag-iimport ng anotasyon mula sa androidx.compose.runtime. Ang pangalan ng function ay inirerekomenda na isulat nang malaking titik — ito ay isang pangkalahatang tinatanggap na convention sa komunidad ng Compose na biswal na nagpapahiwalay ng UI component mula sa ordinaryong function.

kotlin
import androidx.compose.runtime.Composable

@Composable
fun Greeting(name: String) {
    var count by remember { mutableStateOf(0) }
    Column {
        Text("Hello, $name!")
        Button(onClick = { count++ }) {
            Text("Na-click $count beses")
        }
    }
}

Ang mga parameter ng Composable function ay maaaring kahit ano — primitive types, string, lambda, at maging iba pang Composable function na ipinapasa sa pamamagitan ng Slot API. Inirerekomenda na gawing hindi nababago (val) ang mga parameter upang maiwasan ang side effect sa recomposition. Lahat ng nababagong data ay dapat pamahalaan sa pamamagitan ng state mechanism ng Compose.

Ang Composable function ay hindi maaaring magbalik ng arbitraryong value tulad ng ordinaryong function — ang tanging trabaho nila ay bumuo o mag-update ng fragment ng UI tree. Gayunpaman, may mga espesyal na pattern tulad ng State Hoisting, kung saan ang Compose function ay tumatanggap ng estado at callback sa pamamagitan ng parameter, nananatiling dalisay at magagamit muli.

Mga patakaran ng Composable function sa Kotlin

Ang Compose system ay nagpapatupad ng ilang mahigpit na paghihigpit sa kung paano dapat tumingin at kumilos ang Composable function. Unang patakaran: ang Composable function ay maaari lamang tumawag ng iba pang Composable function o ordinaryong function na walang side effect. Tinitiyak nito ang predictability ng komposisyon at tamang trabaho ng Compose optimization.

Ikalawang patakaran ay tungkol sa pagkakasunod-sunod ng execution. Ang Compose ay may karapatang tumawag ng Composable function sa anumang pagkakasunod-sunod, kaya ang code sa katawan ng naturang function ay hindi dapat umasa sa pagkakasunod-sunod ng tawag ng mga kalapit na function. Bawat Composable function ay dapat sapat sa sarili sa antas ng posisyon nito sa UI tree.

Ikatlong patakaran — pagbabawal sa side effect sa loob ng katawan ng Composable function. Ang mga operasyon tulad ng pagsulat sa database, pagpapadala ng network request, o pagbabago ng panlabas na variable ay dapat gawin lamang sa loob ng mga espesyal na effect na LaunchedEffect, DisposableEffect, o SideEffect. Ang paglabag sa patakarang ito ay humahantong sa hindi mahuhulaan na pag-uugali sa recomposition.

Ikaapat na patakaran: Ang Composable function ay dapat idempotent. Ang paulit-ulit na tawag na may parehong argumento ay dapat gumawa ng parehong UI. Ang pangangailangang ito ay kinakailangan para sa tamang trabaho ng skipping optimization, kung saan nilalaktawan ng Compose ang muling pagguhit ng mga function na ang input data ay hindi nagbago.

kotlin
// Tama: dalisay na Composable function na walang side effect
@Composable
fun UserCard(user: User, onClick: () -> Unit) {
    Card(modifier = Modifier.clickable { onClick() }) {
        Text(text = user.name)
    }
}

// Mali: side effect sa loob ng katawan
@Composable
fun WrongCard(userId: String) {
    // val result = viewModel.loadUser(userId)  // HINDI PINAPAYAGAN
    Text("Naglo-load...")
}

Mga halimbawa ng paggamit ng @Composable

Tingnan natin ang praktikal na halimbawa ng paggawa ng profile screen gamit ang anotasyong @Composable. Dito ipinapakita namin ang pagsasama-sama ng maraming Composable function, pagtatrabaho gamit ang estado at modifier — mga pangunahing elemento ng anumang layout ng Compose.

kotlin
@Composable
fun ProfileScreen(userId: String) {
    var isFollowed by remember { mutableStateOf(false) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        ProfileHeader(userId = userId)
        Spacer(modifier = Modifier.height(16.dp))
        StatsRow(posts = 42, followers = 1280)
        Spacer(modifier = Modifier.height(24.dp))
        FollowButton(
            isFollowed = isFollowed,
            onToggle = { isFollowed = !isFollowed }
        )
    }
}

@Composable
fun ProfileHeader(userId: String) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        AsyncImage(model = "https://example.com/avatars/$userId",
            contentDescription = "User avatar")
        Spacer(modifier = Modifier.width(12.dp))
        Text(text = "Gumagamit #$userId", style = MaterialTheme.typography.headlineMedium)
    }
}

@Composable
fun StatsRow(posts: Int, followers: Int) {
    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
        StatItem("Posts", posts)
        StatItem("Followers", followers)
    }
}

@Composable
fun StatItem(label: String, value: Int) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "$value", style = MaterialTheme.typography.headlineSmall)
        Text(text = label, style = MaterialTheme.typography.bodySmall)
    }
}

Sa halimbawa, bawat Composable function ay responsable para sa bahagi nito ng screen: ProfileScreen ay namamahala ng pangkalahatang estado at komposisyon ng mga anak na function, ProfileHeader ay nagpapakita ng avatar at pangalan, at StatsRow — ang bloke na may estadistika. Ang approach na ito ay sumusunod sa prinsipyo ng iisang responsibilidad at pinapasimple ang muling paggamit ng component.

Mga uri ng Composable function at ang kanilang layunin

Sa Jetpack Compose may tatlong pangunahing uri ng Composable function. Unang uri — container (Row, Column, Box, LazyColumn) na tumutukoy sa paglalagay ng mga anak na elemento. Ikalawa — display element (Text, Image, Icon, Button) na nagre-render ng tiyak na UI component. Ikatlo — custom na Composable function na pinagsasama ang built-in na component sa magagamit muling bloke.

Ang container ay naiiba sa ordinaryong elemento dahil tumatanggap sila ng content lambda — huling parameter ng uri @Composable () -> Unit. Ang mekanismong ito ang nagpapahintulot sa pagbuo ng nested UI tree: bawat container ay lumilikha ng anak na komposisyon na may sariling konteksto at lugar ng memorya.

Ang custom na Composable function ay nahahati sa dalawang subtype: matalino (smart) at tanga (dumb). Ang matalinong function ay namamahala ng estado at lohika — naglalaman ng tawag sa remember, LaunchedEffect, at iba pang Compose API. Ang tangang function ay tumatanggap ng lahat ng data sa pamamagitan ng parameter at tanging ipinapakita ang mga ito. Ang paghahati sa matalino at tangang component ay nagpapabuti sa testability at muling paggamit ng code.

UriHalimbawaLayunin
ContainerColumn, Row, BoxPamamahala ng paglalagay ng anak na elemento
ElementoText, Image, ButtonPagpapakita ng nilalaman at pagproseso ng input
CustomProfileCard, UserListKombinasyon ng standard na component

@Composable at muling paggamit ng mga component

Ang pangunahing bentahe ng anotasyong @Composable — kakayahang lumikha ng magagamit muli na UI component nang walang inheritance at kumplikadong class hierarchy. Hindi tulad ng View system, kung saan bawat custom na elemento ay nangangailangan ng paggawa ng Java class na may constructor, ang Composable component ay simpleng Kotlin function na may parameter.

Upang matiyak ang muling paggamit, inilalapat ang pattern na Slot API, kung saan ang Composable function ay tumatanggap ng content lambda para sa iba't ibang lugar ng layout nito. Halimbawa, ang Card component ay maaaring tumanggap ng hiwalay na content para sa header, body, at ibabang bahagi, na ginagawa itong unibersal para sa anumang screen ng application.

Ang Modifier ay may mahalagang papel sa muling paggamit: pinapayagan nila ang pagsasaayos ng mga puwang, sukat, click, at animation nang hindi binabago ang component mismo. Inirerekomenda na palaging ipasa ang Modifier bilang parameter ng Composable function na may default na value: Modifier = Modifier — ito ay standard practice na pinagtibay sa opisyal na Google library.

kotlin
@Composable
fun SectionCard(
    modifier: Modifier = Modifier,
    title: String,
    content: @Composable () -> Unit
) {
    Card(modifier = modifier) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(text = title, style = MaterialTheme.typography.titleMedium)
            Spacer(modifier = Modifier.height(8.dp))
            content()
        }
    }
}

Salamat sa Slot API, ang SectionCard component ay maaaring gamitin sa iba't ibang screen na may iba't ibang nilalaman — form, listahan, text block. Ang kombinasyon ng modifier at Slot API ay ginagawang maximum na flexible ang Compose component nang hindi nawawala ang type safety na ibinibigay ng Kotlin.

Mga Madalas Itanong

Paano naiiba ang @Composable sa ordinaryong Kotlin function?

Ang @Composable function ay isinasagawa sa konteksto ng komposisyon at maaaring magbasa ng estado, awtomatikong nagre-restart kapag nagbago ito. Ang ordinaryong Kotlin function ay walang access sa mekanismo ng pagsubaybay ng estado at hindi nakikilahok sa pagbuo ng UI tree.

Maaari bang tawagan ang Composable function mula sa ordinaryong function?

Hindi, ang Composable function ay maaari lamang tawagan mula sa iba pang Composable function, dahil kinakailangan ang espesyal na konteksto ng komposisyon. Para sa integrasyon ng Compose code sa ordinaryong Kotlin, ginagamit ang setContent { } method sa Activity o ComposeView sa View system.

Bakit isinusulat nang malaking titik ang Composable function?

Ito ay convention sa pagpapangalan na pinagtibay sa komunidad ng Compose. Ang malaking titik ay biswal na nagpapahiwalay ng UI component mula sa ordinaryong function, sumusunod sa rules ng pagpapangalan ng class. Hindi ito requirement ng compiler, ngunit inirerekomendang practice sa dokumentasyon ng Google.

Ilang Composable function ang maaaring nasa isang screen?

Walang limitasyon sa bilang. Sa praktika, ang malaking screen ay maaaring maglaman ng 50–100 Composable function, kasama ang built-in na component (Text, Button) at custom. Ino-optimize ng Compose ang tree ng function at isinasagawa lamang ang mga iyon na ang input data ay nagbago.

Maaari bang magbalik ng value ang Composable function?

Karaniwan ang Composable function ay nagbabalik ng Unit, dahil ang kanilang trabaho ay bumuo ng UI. Gayunpaman, may mga espesyalisadong function tulad ng remember at derivedStateOf na minarkahan ng @Composable at nagbabalik ng value. Ito ay exception, hindi rule.

Buod

  • @Composable — anotasyon para sa deklaratibong paglalarawan ng UI sa Jetpack Compose
  • Composable function ay tinatawag lamang sa loob ng iba pang Composable function sa espesyal na konteksto
  • Idempotency — bawat paulit-ulit na execution na may parehong argumento ay gumagawa ng parehong UI
  • Side effect ay bawal sa katawan ng function — sa pamamagitan lamang ng LaunchedEffect at SideEffect
  • Slot API at Modifier ay tinitiyak ang muling paggamit ng component nang walang inheritance
  • Container function (Row, Column, LazyColumn) ay tumatanggap ng content lambda para sa nested na elemento
  • Rekomendasyon: ipasa ang Modifier bilang parameter ng bawat custom na Composable function na may default na value

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.

Pag-usapan ang proyekto

Basahin din