Jetpack Compose: چیست، مفاهیم کلیدی و توابع composable

نویسنده: IT Sectr منتشر شده: 2026-05-01 زمان مطالعه: 9 دقیقه

Jetpack Compose — یک جعبه ابزار مدرن اعلامی برای ساخت رابط‌های اندروید در Kotlin است. توسعه‌دهنده UI را از طریق توابع composable توصیف می‌کند و جعبه ابزار به طور خودکار فقط بخش‌های تغییر یافته را دوباره ترسیم می‌کند. بر اساس Android Developers (2026)، Jetpack Compose روی Android 5.0 (API 21) و بالاتر کار می‌کند، از Material Design 3 پشتیبانی می‌کند و به لطف سیستم Recomposition خود — یک الگوریتم diff هوشمند که فقط ویجت‌های تغییر یافته را به‌روز می‌کند — به 120 FPS در دستگاه‌های میان‌رده می‌رسد.

نکات اصلی

  • Jetpack Compose — یک چارچوب UI اعلامی برای اندروید است، جایی که رابط کاربری از طریق توابع @Composable در Kotlin ساخته می‌شود.
  • Recomposition — مکانیزم به‌روزرسانی خودکار فقط آن دسته از مؤلفه‌هایی که داده‌هایشان تغییر کرده است، تضمین‌کننده 120 FPS.
  • State از طریق mutableStateOf، collectAsState و StateFlow مدیریت می‌شود — با تغییر مقدار، ترکیب برای نماهای وابسته دوباره راه‌اندازی می‌شود.
  • Modifier — زنجیره‌ای از توابع برای پیکربندی فاصله‌ها، اندازه‌ها، پس‌زمینه، کلیک‌ها و انیمیشن‌ها بدون وراثت کلاس.
  • Side Effects — LaunchedEffect، DisposableEffect و rememberCoroutineScope — اقدامات جانبی را مدیریت می‌کنند: تایمرها، درخواست‌های شبکه، اشتراک‌ها.

Jetpack Compose چیست؟

Jetpack Compose — یک چارچوب اعلامی از Google برای ساخت رابط‌های کاربری اندروید است که در سال 2019 معرفی شد و در سال 2021 به انتشار پایدار رسید. بر خلاف View System قدیمی (XML + Activity/Fragment)، Compose از توابع Kotlin دارای حاشیه‌نویس — @Composable استفاده می‌کند. رابط کاربری به طور کامل در Kotlin توصیف می‌شود: هیچ تقسیم‌بندی بین XML و کد وجود ندارد. این کار کلاس خطاهای مربوط به ناسازگاری id در XML و Kotlin را حذف کرد (type-safe synthetic در بازسازی ساختاری کمکی نمی‌کرد).

Compose روی سیستم رندرینگ خود — Canvas ساخته شده است که به سلسله‌مراتب View وابسته نیست. هر Composable مستقیماً روی Canvas رسم می‌کند و از onMeasure/onDraw View System عبور می‌کند. این باعث افزایش عملکرد در صفحه‌های پیچیده می‌شود: در تست‌های Google (2023)، صفحه Compose با 200 عنصر 40% سریع‌تر از نمونه مشابه در RecyclerView + ViewHolder رندر شد.

حداقل نیازمندی‌ها و سازگاری

برای کار Compose به minSdk 21 (Android 5.0) و Kotlin 1.9+ نیاز دارد. Compose BOM (Bill of Materials) نسخه‌های تمام کتابخانه‌های Compose را همگام‌سازی می‌کند. چارچوب با کد موجود در View System سازگار است: Compose از طریق ComposeView در XML، و نمای قدیمی از طریق AndroidView در سلسله‌مراتب Compose جاسازی می‌شود. طبق داده‌های Google Play Console (2025)، Android 5.0+ 97% دستگاه‌های فعال را پوشش می‌دهد، بنابراین سازگاری برای اکثر پروژه‌ها محدودیت محسوب نمی‌شود.

توابع Composable و ترکیب

@Composable — حاشیه‌نویسی است که یک تابع معمولی Kotlin را به بلوک ساختمانی UI تبدیل می‌کند. تابع Composable توصیف می‌کند که یک قطعه از رابط کاربری — متن، دکمه، لیست — چگونه باید به نظر برسد. این تابع به جای بازگرداندن مقدار، مؤلفه‌های UI را به ترکیب (composition) منتشر می‌کند. این شبیه یک تولیدکننده است: هر تابع در هنگام فراخوانی عناصر را به صفحه اضافه می‌کند.

kotlin
@Composable
fun ProfileCard(name: String, avatarUrl: String) {
    Card(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.surface
        )
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            AsyncImage(
                model = avatarUrl,
                contentDescription = "آواتار",
                modifier = Modifier.size(48.dp).clip(CircleShape)
            )
            Spacer(Modifier.width(12.dp))
            Text(
                text = name,
                style = MaterialTheme.typography.titleMedium
            )
        }
    }
}

تابع ProfileCard پارامترهایی (name، avatarUrl) دریافت می‌کند و Card → Row → AsyncImage + Text منتشر می‌کند. ترکیب (Composition) — درختی از مؤلفه‌های منتشر شده در یک پاس است. اگر پارامترها تغییر نکرده باشند، Compose فراخوانی تابع را رد می‌کند (recomposition skip). اگر فقط name تغییر کرده باشد، فقط Text فراخوانی می‌شود و بقیه عناصر دوباره ترسیم نخواهند شد. چنین intelligent recomposition — مزیت اصلی عملکرد Compose در مقایسه با بهینه‌سازی دستی View System است.

Slot ها و Content Lambda

توابع Composable به طور فعال از slot ها استفاده می‌کنند — trailing lambda، content: @Composable (() -> Unit). این امکان ایجاد کانتینرها را فراهم می‌کند: Card، Column، Row لامبدای content را دریافت می‌کنند و محتوا در محل slot جاسازی می‌شود. Slot API جایگزین ویژگی‌های XML مانند android:layout_gravity شد — اکنون موقعیت عناصر فرزند در داخل بلوک content با کد Kotlin تعیین می‌شود.

مدیریت حالت در Compose

حالت (State) در Compose — هر مقداری است که می‌تواند در طول زمان تغییر کند. وقتی حالت تغییر می‌کند، Compose recomposition را برای تمام مؤلفه‌هایی که این حالت را می‌خوانند برنامه‌ریزی می‌کند. مکانیزم شبیه React hooks است: mutableStateOf MutableState را برمی‌گرداند، خواندن .value به طور خودکار ترکیب فعلی را در تغییرات مشترک می‌کند.

kotlin
@Composable
fun CounterExample() {
    var count by remember { mutableStateOf(0) }

    Column(modifier = Modifier.padding(16.dp)) {
        Text("فشرده شد: $count")
        Button(onClick = { count++ }) {
            Text("افزایش")
        }
    }
}

@Composable
fun UserScreen(viewModel: UserViewModel) {
    val userName by viewModel.userName.collectAsState()
    Text("کاربر: $userName")
}

remember مقدار را بین recomposition ها حفظ می‌کند — در غیر این صورت mutableStateOf در هر به‌روزرسانی UI دوباره ایجاد می‌شد. collectAsState() StateFlow را از ViewModel به حالت سازگار با Compose تبدیل می‌کند. توصیه — برای حالت صفحه از ViewModel با StateFlow، برای حالت محلی (مثلاً کارت باز شده) از mutableStateOf استفاده کنید. این تقسیم‌بندی با اصل مؤلفه‌های «هوشمند/ساده» مطابقت دارد.

State Hoisting

State Hoisting — الگوی انتقال حالت از مؤلفه فرزند به والد است. والد مقدار و callback را از طریق پارامترها منتقل می‌کند، فرزند در زمان تغییر callback را فراخوانی می‌کند. والد mutableStateOf را ذخیره می‌کند، فرزند فقط پارامترها را ذخیره می‌کند. این مؤلفه را قابل استفاده مجدد و قابل آزمایش می‌کند: همان TextField را می‌توان با هر منبع داده‌ای استفاده کرد.

Modifier — پیکربندی ظاهر

Modifier — شیئی است که تبدیل‌های Composable را توصیف می‌کند: اندازه، فاصله‌ها، پس‌زمینه، پردازش کلیک، انیمیشن، اسکرول. اصلاح‌کننده‌ها از طریق زنجیره فراخوانی اعمال می‌شوند: Modifier.fillMaxWidth().padding(16.dp).background(Color.Blue).clickable { }. هر فراخوانی یک Modifier جدید با ویژگی اضافه شده برمی‌گرداند — هیچ تغییر جهتی در شی اصلی رخ نمی‌دهد.

ترتیب اصلاح‌کننده‌ها مهم است. Modifier.padding(16.dp).background(Color.Blue) ناحیه را با فاصله رنگ‌آمیزی می‌کند. Modifier.background(Color.Blue).padding(16.dp) مستطیل داخلی را رنگ‌آمیزی می‌کند و فاصله شفاف باقی می‌ماند. مکانیک شبیه CSS box model است: padding → background مانند margin + background عمل می‌کند؛ background → padding — مانند background + padding در داخل. کافی است توسعه‌دهنده به خاطر بسپارد: padding اول = فاصله خارجی، padding بعد = داخلی.

اصلاح‌کننده‌های سفارشی

اگر اصلاح‌کننده‌های داخلی کافی نباشند، یک اصلاح‌کننده سفارشی از طریق Modifier.composed { ... } یا Modifier.then() ایجاد می‌شود. در داخل اصلاح‌کننده سفارشی می‌توان از اندازه‌گیری‌های layout (Modifier.layout { measurable, constraints -> ... })، رسم (Modifier.drawWithContent { ... })، حرکات (Modifier.pointerInput { ... }) استفاده کرد. مثال: اصلاح‌کننده برای انیمیشن ضربانی هنگام کلیک — اندازه را اندازه‌گیری می‌کند، با کلیک انیمیشن مقیاس را از طریق animateFloatAsState شروع می‌کند.

برای انیمیشن‌ها Compose animate*AsState (animateFloatAsState، animateColorAsState، animateDpAsState) را ارائه می‌دهد — مقادیر بین حالت قدیم و جدید در زمان تغییر انیمیشن می‌شوند. اگر انیمیشن ظاهر/ناپدید شدن نیاز است — AnimatedVisibility و AnimatedContent با انتقال‌های داخلی (fade، slide، expand). همه انیمیشن‌ها روی graphics layer کار می‌کنند و باعث ترکیب اضافی نمی‌شوند.

Side Effects: LaunchedEffect، DisposableEffect، remember

توابع Composable نباید اقدامات جانبی را مستقیماً انجام دهند (درخواست‌های شبکه، تایمرها، اشتراک‌ها) — آنها در هر recomposition فراخوانی می‌شوند که منجر به تکرار درخواست‌ها می‌شود. برای اثرات جانبی Compose خانواده توابع Effect را ارائه می‌دهد: LaunchedEffect هنگام ورود به ترکیب یک کوروتین راه‌اندازی می‌کند و هنگام خروج لغو می‌کند، DisposableEffect — برای منابعی که نیاز به پاک‌سازی صریح دارند (حسگرها، BroadcastReceiver).

kotlin
@Composable
fun SensorReader() {
    val context = LocalContext.current
    var sensorValue by remember { mutableStateOf(0f) }

    DisposableEffect(Unit) {
        val sensor = registerSensorListener(context) { value ->
            sensorValue = value
        }
        onDispose {
            unregisterSensorListener(sensor)
        }
    }

    Text("مقدار: $sensorValue")
}

@Composable
fun UserGreeting(userId: String) {
    LaunchedEffect(userId) {
        val profile = api.fetchProfile(userId)
        // به‌روزرسانی حالت
    }
}

LaunchedEffect(userId) اگر userId تغییر کند دوباره راه‌اندازی می‌شود — کوروتین قبلی لغو می‌شود و کوروتین جدید با userId جدید شروع می‌شود. این کار مدیریت دستی لغو درخواست‌ها را حذف می‌کند. DisposableEffect(Unit) — اثری با کلید ثابت Unit، هنگام ورود به ترکیب فعال می‌شود و هنگام خروج onDispose را فراخوانی می‌کند. SensorReader شنونده را ثبت می‌کند و هنگام خروج از صفحه لغو اشتراک می‌کند — بدون خطر نشت حافظه.

rememberCoroutineScope

اگر کوروتین باید نه هنگام ورود به ترکیب، بلکه با یک رویداد (فشردن دکمه) راه‌اندازی شود، از rememberCoroutineScope() استفاده می‌شود. این تابع CoroutineScope متصل به چرخه حیات Composable را برمی‌گرداند و به DisposableEffect نیاز ندارد. مثال: راه‌اندازی درخواست شبکه با کلیک روی دکمه — scope.launch { viewModel.loadData() }.

Jetpack Compose در مقابل View System: مقایسه

انتخاب بین Compose و View System — سؤال اصلی معماری توسعه‌دهنده اندروید در سال 2026 است. هر دو فناوری توسط Google پشتیبانی می‌شوند، اما Compose جهت اصلی است که Google منابع خود را روی آن متمرکز می‌کند. View System فقط اصلاحات بحرانی دریافت می‌کند و توسعه نمی‌یابد. تفاوت در نحو، مدیریت حالت، عملکرد و زمان توسعه آشکار می‌شود.

جنبهJetpack ComposeView System
توصیف UIتوابع Kotlin @ComposableXML + Activity/Fragment
حالتmutableStateOf، StateFlow، ترسیم مجدد خودکارfindViewById، دستی: setText، notifyDataSetChanged
عملکردIntelligent recomposition، رندر Canvasسلسله‌مراتب View، measure/layout/draw
انیمیشن‌هاanimate*AsState، AnimatedVisibility، داخلیValueAnimator، ObjectAnimator، Transition
سازگاریminSdk 21، پل‌های ComposeView/AndroidViewهمه نسخه‌ها
اندازه APK3-5+ مگابایت برای Composeبدون سربار اضافی

برای پروژه‌های جدید Google Jetpack Compose را به عنوان استاندارد توسعه UI توصیه می‌کند. View System برای پشتیبانی از کد نوشته شده قبل از 2021 و مواردی که اندازه حداقلی APK مورد نیاز است (مثلاً برای بازارهای در حال توسعه با دستگاه‌های سطح ابتدایی) باقی می‌ماند. Compose حجم کد UI را 30-50% در مقایسه با View System به دلیل نحو اعلامی و انیمیشن‌های داخلی کاهش می‌دهد.

سوالات متداول

آیا می‌توان از Compose در پروژه موجود در View System استفاده کرد؟

بله، از طریق ComposeView در XML. وابستگی Compose را اضافه کنید و صفحه یا بخشی از آن را در ComposeView { MyComposable() } قرار دهید. مهاجرت صفحه به صفحه انجام می‌شود.

چرا Composable من بیش از حد مکرر دوباره ترسیم می‌شود؟

دلیل — حالت خیلی بالا منتقل می‌شود یا از اشیاء قابل تغییر استفاده می‌شود. رفع: derivedStateOf برای داده‌های مشتق شده و remember برای ارجاعات پایدار.

چگونه یک لیست در Compose پیاده‌سازی کنیم؟

از LazyColumn (معادل RecyclerView) استفاده کنید. عناصر در حین اسکرول ایجاد و مجدداً استفاده می‌شوند. برای لیست‌های پیچیده با انواع مختلف سلول — LazyColumn { items(items, key = { it.id }) { ... } }.

آیا باید قبل از Compose View System را یاد بگیرم؟

خیر، می‌توانید مستقیماً با Compose شروع کنید. آشنایی با View System برای پشتیبانی از کد قدیمی کمک می‌کند، اما Compose یک اکوسیستم مستقل با مستندات و الگوهای خاص خود است.

آیا Compose از Material 3 پشتیبانی می‌کند؟

بله، Material 3 — تم استاندارد Compose از سال 2023 است. از طریق implementation("androidx.compose.material3:material3") متصل می‌شود. Material 2 منسوخ شده در نظر گرفته می‌شود.

خلاصه

  • Jetpack Compose — یک چارچوب UI اعلامی برای اندروید است که کل رابط کاربری در Kotlin از طریق توابع @Composable نوشته می‌شود.
  • Recomposition به طور خودکار فقط مؤلفه‌های تغییر یافته را دوباره ترسیم می‌کند و بدون بهینه‌سازی دستی 120 FPS را تضمین می‌کند.
  • حالت از طریق mutableStateOf، collectAsState و StateFlow مدیریت می‌شود؛ الگوی State Hoisting مؤلفه‌ها را قابل استفاده مجدد می‌کند.
  • Modifier — زنجیره‌ای از تبدیل‌ها برای پیکربندی ظاهر، انیمیشن و رفتار بدون وراثت کلاس.
  • Side Effects (LaunchedEffect، DisposableEffect) اقدامات جانبی را از recomposition جدا می‌کنند و از نشت حافظه و تکرار درخواست‌ها جلوگیری می‌کنند.
  • LazyColumn جایگزین RecyclerView با کد کمتر می‌شود و AnimatedVisibility جایگزین زنجیره‌های پیچیده Animator می‌شود.
  • Google Compose را برای همه پروژه‌های جدید توصیه می‌کند؛ View System برای پشتیبانی از کد قدیمی و مواردی که اندازه حداقلی APK حیاتی است باقی می‌ماند.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید