Jetpack Compose: الأساسيات، دوال Composable والحالة

المؤلف: IT Sectr نُشر: 2026-02-21 وقت القراءة: 8 دق

Jetpack Compose هو إطار عمل واجهة مستخدم تعريفي حديث من Google لتطوير Android، تم إصداره في النسخة المستقرة 1.0 في يوليو 2021. يستبدل Compose تخطيط XML الأمرّي ونظام View بدوال Kotlin مع التعليق التوضيحي @Composable. وفقًا لـ Google I/O (2025)، يُستخدم Compose في 55% من المشاريع الجديدة على Android، وينخفض متوسط حجم كود UI بنسبة 30–50% مقارنة بـ XML. يقوم الإطار بإعادة رسم الأجزاء المتغيرة فقط من الشاشة تلقائيًا عند تغيير State، مما يلغي الحاجة إلى استدعاءات notifyDataSetChanged أو findViewById اليدوية.

النقاط الرئيسية

  • Jetpack Compose — إطار عمل واجهة مستخدم تعريفي من Google لنظام Android بلغة Kotlin (دوال @Composable بدلاً من تخطيط XML).
  • @Composable — تعليق توضيحي للدالة يصف جزءًا من واجهة المستخدم، يمكنه قبول المعاملات وقراءة State.
  • State و MutableState — آلية التفاعلية: عند تغيير State، يعيد Compose تشغيل (recompose) دوال Composable المعتمدة فقط.
  • remember — دالة تخزين مؤقت للقيم بين عمليات إعادة التركيب؛ بدونها يتم إعادة تعيين State مع كل تحديث.
  • Modifier — سلسلة من الإعدادات (padding, size, clickable, background) تتحكم في مظهر وسلوك المكون Composable.

ما هو Jetpack Compose؟

Jetpack Compose هو إطار عمل واجهة مستخدم من Google مبني على مبادئ البرمجة التفاعلية. بدلاً من Activity مع تخطيط XML و FragmentManager و ViewBinding، يصف المطور الواجهة من خلال دوال Kotlin مع التعليق التوضيحي @Composable. لا يستخدم Compose LayoutInflater — واجهة المستخدم هي دوال Kotlin نقية تُترجم إلى bytecode. يتكون الإطار من عدة مكتبات: Compose UI (المكونات الأساسية Text, Button, Column, Row)، Compose Foundation (Material Design, Gestures, Focus)، Compose Material3 (Material You مع Dynamic Colors) و Compose Runtime (State, Side Effects, Coroutines). يعمل Compose على Android API 21+ (Android 5.0) ومتوافق تمامًا مع كود View/XML الموجود من خلال ComposeView — محوّل AndroidView.

Compose مقابل View System

View System (2008) يستخدم تسلسلاً هرميًا لكائنات View مع إدارة يدوية: ينشئ المطور تخطيط XML، ويجد Views عبر findViewById، وينفذ Adapter لـ RecyclerView ويستدعي notifyDataSetChanged عند تغيير البيانات. يصف Compose واجهة المستخدم وظيفيًا: عندما تتغير الحالة، يعيد الإطار تشغيل (recompose) دوال Composable المتغيرة فقط، ويحسب الفرق (diff) ويطبق الحد الأدنى من التغييرات على Canvas. أداء Compose مشابه لـ View System، وفي سيناريوهات القوائم المعقدة (LazyColumn) غالبًا ما يتفوق على RecyclerView بفضل تخطي العناصر غير الضرورية عبر معامل key. في IT Sectr، يُستخدم Compose للوحدات الجديدة من تطبيقات Android مع minSdk 24+.

دوال Composable: اللبنات الأساسية لواجهة المستخدم

@Composable — تعليق توضيحي يحول دالة Kotlin عادية إلى لبنة بناء لواجهة المستخدم. يمكن لدوال Composable استدعاء دوال Composable أخرى، لتكوين شجرة من المكونات. على عكس View، دوال Composable ليس لها حالة افتراضيًا — فهي عديمة الحالة (stateless) وتُعاد رسمها مع كل تغيير في معاملات الإدخال أو State. يقوم Compose Compiler بتحويل دوال @Composable إلى كود يمكن مقاطعته واستئنافه (positional memoization) — مما يسمح لـ Compose بإعادة تشغيل الأجزاء المتغيرة فقط دون إعادة بناء الشجرة بالكامل.

kotlin
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun UserProfile(name: String, avatarUrl: String) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        AsyncImage(
            model = avatarUrl,
            contentDescription = "User avatar",
            modifier = Modifier.size(48.dp)
        )
        Spacer(modifier = Modifier.width(12.dp))
        Text(
            text = name,
            style = MaterialTheme.typography.titleMedium
        )
    }
}

تستقبل الدالة UserProfile name و avatarUrl كمعاملات، وتبني صفًا مع صورة رمزية واسم. Modifier.fillMaxWidth() يمدد المكون عبر العرض بالكامل، .padding(16.dp) يضيف حشوة. يستخدم MaterialTheme.typography.titleMedium نمط النظام Material 3. عندما تتغير معاملات name أو avatarUrl، يعيد Compose تشغيل UserProfile — إعادة إنشاء المكون بقيم جديدة.

State و Recomposition في Jetpack Compose

State في Compose هو أي قيمة يؤدي تغييرها إلى إعادة التركيب (إعادة تشغيل) دوال @Composable المعتمدة. الطريقة الأساسية هي mutableStateOf()، التي تنشئ MutableState<T> مع دعم نظام snapshot في Compose. Snapshot هي آلية تتبع التغييرات: عند كتابة State، يضع Compose علامة على Snapshot الحالي كـ dirty، ويقوم مُجدوِل إعادة التركيب بإعادة تشغيل دوال Composable التي تقرأ هذا State فقط. للمجموعات القابلة للمراقبة استخدم mutableStateListOf() و mutableStateMapOf(). يدعم Compose State من مكونات Lifecycle-Aware عبر collectAsState() لـ Kotlin Flow و observeAsState() لـ LiveData.

kotlin
@Composable
fun LikeButton() {
    var liked by remember { mutableStateOf(false) }
    var count by remember { mutableStateOf(42) }
    
    Button(
        onClick = {
            liked = !liked
            if (liked) count++ else count--
        },
        colors = ButtonDefaults.buttonColors(
            containerColor = if (liked) MaterialTheme.colorScheme.primary
                else MaterialTheme.colorScheme.surfaceVariant
        )
    ) {
        Text("♥ $count")
    }
}

ينشئ الكود زر "Like" مع حالة liked (Boolean) و count (Int) مخزنتين عبر mutableStateOf(). عند الضغط، يتم عكس liked ويزداد/ينقص العداد — يقوم Compose تلقائيًا بإعادة تشغيل LikeButton. يسمح المفوض by باستخدام State كمتغير عادي: liked = !liked بدلاً من liked.value = !liked.value. يتغير لون الزر تفاعليًا بين primary (تم الإعجاب) و surfaceVariant (لم يتم الإعجاب).

remember: التخزين المؤقت بين عمليات إعادة التركيب

remember — دالة Compose تخزن قيمة مؤقتًا بين عمليات إعادة التركيب. بدون remember، كل إعادة تشغيل لدالة Composable تنشئ حالة جديدة (mutableStateOf) — وهذا يعطل منطق التطبيق: عند تدوير الشاشة أو تغيير State الأب، يتم إعادة تعيين العداد. تقبل remember تعبير lambda للحساب وتحسب القيمة فقط في أول تركيب؛ في المرات التالية تعيد النتيجة المخزنة مؤقتًا. لإعادة تعيين التخزين المؤقت استخدم remember(key) — يحدد المفتاح متى يُعاد حساب القيمة. remember(key1, key2) يعيد الحساب عند تغيير أي مفتاح. للحالات طويلة العمر (التي تتحمل تدوير الشاشة) استخدم rememberSaveable — شبيه remember مع الحفظ في Bundle عبر SavedStateHandle.

kotlin
@Composable
fun TimerScreen() {
    var seconds by rememberSaveable { mutableStateOf(0) }
    
    LaunchedEffect(Unit) {
        while (true) {
            delay(1000)
            seconds++
        }
    }
    
    Column(
        modifier = Modifier.fillMaxSize().padding(32.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Elapsed: ${seconds}s",
            style = MaterialTheme.typography.displayMedium
        )
    }
}

rememberSaveable يحتفظ بـ seconds عند تدوير الشاشة (تغيير الإعدادات). يقوم LaunchedEffect بتشغيل coroutine يزيد seconds كل ثانية. عند إعادة تركيب TimerScreen (كل ثانية) لا يتم إعادة تعيين seconds بفضل rememberSaveable. استخدم remember العادي للحالة التي لا يجب أن تتحمل تغييرات الإعدادات (مثلاً، أعلام الرسوم المتحركة).

Modifier: سلسلة إعدادات Composable

Modifier — كائن حاوية غير قابل للتغيير يطبق نمط Builder لتكوين مظهر وسلوك وتخطيط مكونات Composable. كل استدعاء لطريقة Modifier (.padding(), .width(), .clickable(), .background()) يعيد Modifier جديد مع العنصر المضاف. ترتيب المعدّلات مهم: .padding(16.dp).clickable { } — تُطبق الحشوة قبل معالج النقر، clickable يتتبع المساحة بأكملها بما في ذلك الحشوة. .clickable { }.padding(16.dp) — المساحة بأكملها قبل الحشوة قابلة للنقر، الحشوة تزيح المحتوى للداخل. يدعم Modifier التطبيقات المخصصة عبر then(otherModifier) و compositionLocal للوصول إلى إعدادات الأب.

kotlin
@Composable
fun CardExample() {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
            .clickable { println("Card clicked") },
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.surfaceVariant
        )
    ) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text("Jetpack Compose", style = MaterialTheme.typography.titleLarge)
            Spacer(modifier = Modifier.height(8.dp))
            Text(
                "UI تعريفية لنظام Android مع State و Modifier",
                style = MaterialTheme.typography.bodyMedium
            )
        }
    }
}

يُظهر CardExample سلسلة Modifier: fillMaxWidth + padding + clickable. Card هو مكون Material3 مع إعدادات elevation و colors خاصة به. يحتوي Column المتداخل على حشوة داخلية 16dp. يقوم Compose Material3 بتكييف الألوان تلقائيًا مع Dynamic Color (Material You) على Android 12+. Card هو واحد من أكثر من 30 مكون Material3 مدمج في Compose.

رفع الحالة State hoisting وهندسة Compose

State hoisting — نمط رفع الحالة من دالة Composable إلى المستدعي، مما يجعل الدالة عديمة الحالة (stateless). المكون عديم الحالة يستقبل البيانات واستدعاءات回调 عبر المعاملات دون امتلاك State بنفسه. هذا يحسن قابلية إعادة الاستخدام والاختبار: يمكن استدعاء المكون مع States مختلفة واختباره في preview. توصي Google بالهندسة: ViewModel + StateFlow (أو MutableStateFlow) + collectAsState() في Compose. يرفع ViewModel الحالة إلى مستوى الشاشة، ويقوم Compose بعرضها. تعالج التأثيرات الجانبية (LaunchedEffect, DisposableEffect) الأحداث لمرة واحدة.

المكونالمسؤوليةالتقنية
ViewModelتخزين الحالة، منطق الأعمالStateFlow, MutableStateFlow
Screen Composableتنظيم الشاشة، رفع الحالةcollectAsState(), Scaffold, LazyColumn
Stateless Componentواجهة مستخدم بدون حالة، عرض نقيمعاملات @Composable + lambdas
Side Effectإجراءات لمرة واحدة (snackbar, تنقل)LaunchedEffect, SnackbarHostState

الأسئلة الشائعة

كيف يختلف Jetpack Compose عن تخطيط XML؟

تخطيط XML أمري: LayoutInflater يحمّل XML، findViewById يجد Views، المطور يحدّث النص/القوائم يدويًا. Compose تعريفي: توصف واجهة المستخدم بدوال Kotlin @Composable، ويعيد الإطار رسم الأجزاء المتغيرة فقط تلقائيًا عند تغيير State. يقلل Compose حجم كود UI بنسبة 30–50% ولا يستخدم XML.

هل أحتاج إلى مكتبة منفصلة للتنقل في Compose؟

نعم، توفر Google Navigation Compose — مكتبة للتنقل التعريفي بين الشاشات. يدير NavController مكدس المسارات، يسجّل composable() الشاشات، يمرّر navArgument المعاملات. البدائل: Voyager (community) و Decompose (Badoo). Navigation Compose هو المعيار الرسمي مع دعم deep links والوسيطات type-safe.

ما هو Modifier في Jetpack Compose؟

Modifier هو حاوية غير قابلة للتغيير لأنماط الزخرفة (padding, size, clickable, background, border, clip) تُطبّق على مكونات Composable. كل استدعاء يعيد Modifier جديد مع العنصر المضاف. الترتيب مهم: .padding().clickable() يطبق الحشوة قبل النقر، .clickable().padding() — العكس. Modifier هو الطريقة الأساسية لتخصيص مكونات Compose.

هل يعمل Compose على جميع إصدارات Android؟

يدعم Jetpack Compose Android API 21+ (Android 5.0 Lollipop) من خلال Compose Compiler و Compose BOM. Material 3 (Dynamic Colors) متاح على Android 12+؛ على الإصدارات الأقدم تُستخدم لوحة fallback. للمشاريع الجديدة، توصي Google بـ minSdk 24+ (Android 7.0)، وهو مغطى بالكامل بواسطة Compose.

كيفية اختبار مكونات Compose؟

توفر Google Compose UI Test — مكتبة للاختبار على JVM (سطح المكتب) والمحاكي. الوظائف الرئيسية: composeTestRule.setContent { } لعرض المكون، onNodeWithText() للبحث عن العناصر، performClick()/performTextInput() للإجراءات. اختبارات Espresso متوافقة مع Compose عبر ComposeTestRule، لكن Compose UI Test هو النهج المفضل والأسرع.

الخلاصة

  • Jetpack Compose — إطار عمل واجهة مستخدم تعريفي من Google لنظام Android مع دوال Kotlin @Composable بدلاً من XML (مستقر منذ 2021).
  • @Composable — تعليق توضيحي يحول دالة Kotlin إلى مكون واجهة مستخدم؛ شجرة دوال Composable تحل محل تسلسل View الهرمي.
  • State و mutableStateOf — أساس التفاعلية في Compose عبر نظام Snapshot؛ إعادة التركيب تؤثر فقط على الدوال المعتمدة.
  • remember يخزّن قيمة مؤقتًا بين عمليات إعادة التركيب؛ rememberSaveable يحافظ على State عند تغييرات الإعدادات.
  • Modifier — سلسلة إعدادات (padding, size, clickable, background) تشكل حاوية غير قابلة للتغيير؛ ترتيب المعدّلات مهم.
  • State hoisting — نمط رفع الحالة لأعلى للمكونات عديمة الحالة؛ ViewModel + StateFlow + collectAsState() هي الهندسة الموصى بها.
  • Material 3 مع Dynamic Colors (Android 12+) هو السمة القياسية لـ Compose مع تكيف تلقائي مع خلفية الجهاز.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا