LazyColumn في Jetpack Compose — ما هي، الخصائص وكيف تعمل

المؤلف: IT Sectr نُشر: 2026-06-29 وقت القراءة: 11 دق

LazyColumn هي دالة composable في Jetpack Compose لإنشاء قوائم عمودية مع تحميل بطيء للعناصر. على عكس Column، تقوم LazyColumn بإنشاء وتركيب العناصر المرئية فقط على الشاشة، وإعادة استخدامها أثناء التمرير. وفقًا لـ Google Android Documentation, 2025، تعتبر LazyColumn الأداة الرئيسية لعرض مجموعات البيانات الكبيرة في التطبيقات المحمولة بفضل إدارة الذاكرة الفعالة.

الملامح الرئيسية

  • LazyColumn — قائمة عمودية في Jetpack Compose مع تحميل بطيء تنشئ العناصر المرئية فقط وتعيد استخدامها أثناء التمرير.
  • items تقبل مجموعة بيانات ودالة مصنع لإنشاء عناصر القائمة، بينما يضيف item مكونات فردية.
  • LazyListState يتتبع موضع التمرير ويسمح بالتحكم البرمجي في القائمة عبر animateScrollToItem و scrollToItem.
  • Sticky headers تثبت رؤوس الأقسام في أعلى القائمة أثناء التمرير باستخدام stickyHeader.
  • LazyColumn تدعم أنواعًا مختلفة من العناصر عبر معامل contentType لتحسين إعادة الاستخدام.

ما هي LazyColumn في Jetpack Compose

LazyColumn هي دالة composable تنفذ قائمة عمودية قابلة للتمرير مع تحميل بطيء. على عكس Column الذي يعرض جميع العناصر الفرعية مرة واحدة، تنشئ LazyColumn العناصر الموجودة داخل منطقة العرض فقط.

تعتمد آلية التحميل البطيء في LazyColumn على إعادة استخدام العناصر: عندما يتم إخفاء عنصر أثناء التمرير، يمكن إعادة استخدام تركيبه وتخطيطه لعنصر جديد يظهر. وهذا يوفر الذاكرة ووقت المعالج، خاصة في القوائم الطويلة.

وفقًا لـ Android Developers Blog, 2024، يمكن لـ LazyColumn التعامل بكفاءة مع قوائم تحتوي على عشرات الآلاف من العناصر دون تدهور كبير في الأداء. كل عنصر في LazyColumn لديه مفتاح (key) يساعد Compose في تحديد وحالة العنصر والحفاظ عليها عندما تتغير القائمة.

التوقيع الأساسي لـ LazyColumn

LazyColumn تقبل المعاملات modifier و state و contentPadding و reverseLayout و verticalArrangement و horizontalAlignment. يتم تعريف المحتوى في كتلة lambda عبر دوال DSL items و item.

kotlin
@Composable
fun SimpleLazyColumn() {
    val itemsList = (1..100).toList()
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        contentPadding = PaddingValues(16.dp)
    ) {
        items(itemsList) { item ->
            Text(text = "العنصر $item")
        }
    }
}

معاملات LazyColumn: items و item

توفر كتلة DSL الخاصة بـ LazyColumn الدوال items و item لإضافة المحتوى. تقبل items مجموعة بيانات ومفتاحًا ودالة مصنع لإنشاء العناصر. يضيف item عنصرًا ثابتًا واحدًا إلى القائمة.

itemsIndexed هي نسخة من items تمرر فهرس العنصر بالإضافة إلى البيانات. وهذا مفيد عندما تحتاج إلى معرفة موضع العنصر دون حساب منفصل. items(size) تقبل فقط عدد العناصر ومصنعًا دون الارتباط بمجموعة.

معامل key في items يحدد كل عنصر بشكل فريد. وفقًا لـ Material Design Guidelines, 2025، تعمل المفاتيح على تحسين الأداء عند تحديث العناصر وتحريكها، حيث يمكن لـ Compose تتبع حركة أو تغيير عنصر معين بواسطة مفتاحه.

مثال مع أنواع مختلفة من العناصر

تسمح دالة items مع contentType لـ LazyColumn بتحسين إعادة استخدام العناصر من أنواع مختلفة. في المثال أدناه، يتم استخدام رؤوس الأقسام والصفوف العادية في قائمة واحدة.

kotlin
@Composable
fun MixedItemsList() {
    LazyColumn {
        item {
            Text(
                text = "رأس",
                style = MaterialTheme.typography.headlineMedium
            )
        }
        items(
            items = (1..20).toList(),
            key = { it },
            contentType = { "item" }
        ) { item ->
            Text(text = "الصف $item")
        }
    }
}

LazyListState وإدارة التمرير

LazyListState هو كائن حالة LazyColumn الذي يتتبع موضع التمرير الحالي وأول عنصر مرئي والإزاحة. يمكن إنشاؤه عبر rememberLazyListState() وتمريره إلى معامل state في LazyColumn.

LazyListState يوفر طريقتي animateScrollToItem و scrollToItem للتمرير البرمجي إلى عنصر معين. تنشئ animateScrollToItem رسمًا متحركًا سلسًا للتمرير، بينما يقوم scrollToItem بالتمرير فوريًا. تتطلب كلتا الطريقتين الاستدعاء داخل coroutine في CompositionContext.

وفقًا لـ Android Developers, 2024، يحتوي LazyListState أيضًا على layoutInfo الذي يوفر معلومات حول العناصر المرئية — فهارسها وإزاحاتها وأحجامها. وهذا مفيد لتنفيذ التحليلات وتتبع المشاهدات أو التمرير اللانهائي.

مثال مع التمرير البرمجي

في هذا المثال، يتم التحكم في LazyColumn عبر LazyListState. يقوم زر بتمرير القائمة إلى العنصر ذي الفهرس 50 برسوم متحركة سلسة.

kotlin
@Composable
fun ScrollableList() {
    val listState = rememberLazyListState()
    val scope = rememberCoroutineScope()

    Column {
        Button(
            onClick = {
                scope.launch {
                    listState.animateScrollToItem(50)
                }
            }
        ) {
            Text("تمرير إلى 50")
        }

        LazyColumn(state = listState) {
            items((1..100).toList()) { item ->
                Text(
                    text = "العنصر $item",
                    modifier = Modifier.padding(8.dp)
                )
            }
        }
    }
}

تحسين أداء LazyColumn

عامل الأداء الرئيسي لـ LazyColumn هو الاستخدام الصحيح للمفاتيح. يجب أن يكون لكل عنصر مفتاح مستقر فريد عبر معامل key. بدون مفاتيح، لا يمكن لـ Compose إعادة استخدام العناصر بشكل صحيح عندما تتغير البيانات، مما يؤدي إلى إعادة التركيب.

contentType يخبر LazyColumn بالعناصر التي لها نفس نوع التخطيط. عندما يدخل عنصران لهما نفس contentType إلى مجموعة إعادة التدوير، يمكن لـ LazyColumn إعادة استخدام تخطيطهما دون إعادة تركيب. وفقًا لـ Android Developers Blog, 2024، يحسن contentType الأداء بنسبة 30–50% في القوائم ذات الأنواع المختلفة من العناصر.

بالنسبة لـ LazyColumn، من المهم أيضًا تجنب المعاملات غير المستقرة في دوال المصنع. في كل مرة يتغير فيها معامل عنصر، يعيد Compose تركيب ذلك العنصر. استخدام remember و derivedStateOf للقيم المستقرة يقلل من عدد عمليات إعادة التركيب.

جدول عوامل الأداء

العاملالتأثيرالتوصية
المفاتيح (key)حرجحدد دائمًا مفتاحًا مستقرًا فريدًا لـ items
contentTypeكبيرحدد نوع العنصر لتحسين إعادة الاستخدام
حجم العناصرمتوسطاستخدم أحجامًا ثابتة حيثما أمكن
القوائم المتداخلةحرجتجنب LazyColumn داخل LazyColumn — استخدم LazyVerticalGrid

Sticky headers والأقسام في LazyColumn

stickyHeader هي دالة DSL في LazyColumn تثبت رأس القسم في أعلى القائمة أثناء التمرير. عندما يصل القسم التالي إلى الأعلى، يحل محله رأسه. هذا السلوك مألوف للمستخدمين من قوائم جهات الاتصال والتقويمات.

stickyHeader يقبل مفتاحًا ودالة مصنع، على غرار item. على عكس العنصر العادي، يبقى stickyHeader مرئيًا أثناء التمرير عبر محتوى قسمه. عندما يتم تمرير القسم بالكامل، يدفع رأس القسم التالي الرأس السابق للخارج.

وفقًا لـ Material Design Guidelines, 2025، تعمل الرؤوس الثابتة على تحسين التنقل في القوائم الطويلة وتقليل العبء المعرفي على المستخدم. لتطبيق رأس ثابت، ما عليك سوى لف رأس القسم في stickyHeader في الموضع الصحيح بالنسبة لعناصر items.

kotlin
@Composable
fun SectionedList(sections: Map<String, List<String>>) {
    LazyColumn {
        sections.forEach { (header, items) ->
            stickyHeader {
                Text(
                    text = header,
                    modifier = Modifier.background(Color.White)
                        .padding(16.dp)
                )
            }
            items(items) { item ->
                Text(text = item, modifier = Modifier.padding(8.dp))
            }
        }
    }
}

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

كيف يختلف LazyColumn عن Column في Compose؟

Column يعرض جميع العناصر مرة واحدة ومناسب للقوائم التي تحتوي على 20–30 عنصرًا. LazyColumn تنشئ العناصر المرئية فقط وتعيد استخدامها أثناء التمرير، مما يسمح بالعمل مع آلاف العناصر دون فقدان الأداء.

كيف أضيف فواصل بين عناصر LazyColumn؟

استخدم Arrangement.spacedBy في معامل verticalArrangement أو دوال items مع فاصل عبر الفهرس. للفواصل المعقدة، أضف عنصرًا منفصلاً مع Divider() بين عناصر القائمة.

كيف أحدث LazyColumn عند تغيير البيانات؟

LazyColumn تعيد التركيب تلقائيًا عندما تتغير مجموعة البيانات، إذا تم استخدام مفاتيح مستقرة. تؤدي تغييرات البيانات المكتشفة عبر mutableStateListOf أو StateFlow إلى إعادة رسم العناصر المتغيرة فقط.

هل يمكن تداخل LazyColumn داخل LazyColumn؟

التداخل المباشر لـ LazyColumn داخل LazyColumn غير موصى به — كلاهما لهما تمرير مستقل، مما يخلق تعارضًا في الإيماءات. بدلاً من ذلك، استخدم Column عادي مع LazyColumn داخل Section قابلة للتمرير أو LazyVerticalGrid للشبكات.

كيف أكتشف أن LazyColumn قد تم تمريرها حتى النهاية؟

استخدم LazyListState.layoutInfo.visibleItemsInfo وقارن فهرس آخر عنصر مرئي مع العدد الإجمالي للعناصر. للتمرير اللانهائي، تتبع عندما يقترب آخر عنصر مرئي من نهاية القائمة.

الخلاصة

  • LazyColumn — قائمة عمودية مع تحميل بطيء تنشئ وتعيد استخدام العناصر في منطقة العرض فقط للعمل بكفاءة مع البيانات الكبيرة.
  • items و item — دوال DSL لإضافة مجموعات البيانات والمكونات الفردية إلى LazyColumn مع دعم المفاتيح و contentType.
  • LazyListState يدير موضع التمرير، مما يوفر تنقلًا برمجيًا عبر animateScrollToItem و scrollToItem في coroutines.
  • contentType و key — أدوات تحسين الأداء الرئيسية، تقلل إعادة التركيب وتحسن إعادة استخدام العناصر.
  • stickyHeader يثبت رؤوس الأقسام في أعلى القائمة، مما يحسن التنقل في القوائم الطويلة ذات البيانات المجمعة.
  • Arrangement.spacedBy و contentPadding يديران المسافات بين العناصر وحواف LazyColumn للتوافق مع Material Design.
  • للقوائم الأفقية مع التحميل البطيء، استخدم LazyRow، وللشبكات — LazyVerticalGrid، باتباع نفس مبدأ التحميل البطيء.

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

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

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

اقرأ أيضًا