أخبار المنتجات

الميزات الجديدة في إصدار Jetpack Compose لشهر أبريل 2026

يستغرق الاطّلاع على المقال 6 دقائق
عرض الملف الشخصي لـ Meghan Mehta
Meghan Mehta مسؤول علاقات المطوّرين، Android

أصبح إصدار أبريل 2026 من Jetpack Compose ثابتًا اليوم. يتضمّن هذا الإصدار الإصدار 1.11 من وحدات Compose الأساسية (راجِع عمليات ربط حزمة إدارة المواد الكاملة)، وأدوات تصحيح أخطاء العناصر المشترَكة، وأحداث لوحة اللمس، وغير ذلك. لدينا أيضًا بعض واجهات برمجة التطبيقات التجريبية التي نودّ أن تجربها وتشاركنا ملاحظاتك بشأنها.

لاستخدام الإصدار الحالي، يجب ترقية إصدار Compose BOM إلى:

implementation(platform("androidx.compose:compose-bom:2026.04.01"))

التغييرات في Compose 1.11.0

تنفيذ الروتينات المشتركة في الاختبارات

نحن بصدد طرح تحديث رئيسي على طريقة تعامل Compose مع توقيت الاختبار. بعد فترة الموافقة التي تم الإعلان عنها في Compose 1.10، أصبحت واجهات برمجة التطبيقات لاختبار الإصدار 2 هي الإعداد التلقائي، وتم إيقاف الإصدار 1 من واجهات برمجة التطبيقات نهائيًا. التغيير الرئيسي هو التحوّل في أداة إرسال الاختبار التلقائية. في حين أنّ واجهات برمجة التطبيقات الإصدار 1 كانت تعتمد على UnconfinedTestDispatcher الذي ينفّذ الروتينات الفرعية على الفور، تستخدم واجهات برمجة التطبيقات الإصدار 2 StandardTestDispatcher. وهذا يعني أنّه عند تشغيل روتين فرعي في اختباراتك، يتم الآن وضعه في قائمة الانتظار ولا يتم تنفيذه إلى أن يتم تقديم الساعة الافتراضية.

ويحاكي ذلك ظروف الإنتاج بشكل أفضل، ما يؤدي إلى التخلص من حالات التعارض وجعل مجموعة الاختبار أكثر قوة وأقل عرضة للأخطاء.

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

تحسينات على العناصر المشترَكة وأدوات الصور المتحركة

أضفنا أيضًا بعض أدوات تصحيح الأخطاء المرئية المفيدة للعناصر المشتركة و Modifier.animatedBounds. يمكنك الآن رؤية ما يحدث بالضبط في الخفاء - مثل حدود الهدف، ومسارات الرسوم المتحركة، وعدد التطابقات التي تم العثور عليها - مما يجعل من السهل جدًا تحديد سبب عدم تصرف الانتقال كما هو متوقع. لاستخدام الأدوات الجديدة، ما عليك سوى وضع عنصر SharedTransitionLayout الخاص بك داخلLookaheadAnimationVisualDebugging قابل للتركيب. 

LookaheadAnimationVisualDebugging(
    overlayColor = Color(0x4AE91E63),
    isEnabled = true,
    multipleMatchesColor = Color.Green,
    isShowKeylabelEnabled = false,
    unmatchedElementColor = Color.Red,
) {
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalSharedTransitionScope provides this,
        ) {
            // your content
        }
    }
}

أحداث لوحة اللمس

لقد قمنا بتحديث دعم Compose للوحات اللمس، مثل لوحات اللمس المدمجة في أجهزة الكمبيوتر المحمولة، ولوحات اللمس القابلة للتوصيل بالأجهزة اللوحية، أو لوحات اللمس الخارجية/الافتراضية. ستُعتبر أحداث لوحة اللمس الأساسية الآن بشكل عام أحداث PointerType.Mouse، مما يؤدي إلى مواءمة سلوك الماوس ولوحة اللمس ليتناسب بشكل أفضل مع توقعات المستخدم. في السابق، كانت أحداث لوحة اللمس هذه تُفسر على أنها أصابع شاشة لمس وهمية لـ PointerType.Touch، مما أدى إلى تجارب مستخدم مربكة. على سبيل المثال، النقر والسحب باستخدام لوحة اللمس سيؤدي إلى التمرير بدلاً من التحديد. من خلال تغيير نوع المؤشر لهذه الأحداث في أحدث إصدار من Compose، لن يؤدي النقر والسحب باستخدام لوحة اللمس إلى التمرير بعد الآن.

أضفنا أيضًا دعمًا لإيماءات لوحة اللمس الأكثر تعقيدًا كما تتعرف عليها المنصة منذ API 34، بما في ذلك التمرير بإصبعين و الضغط على بعضهما البعض. يتم التعرف على هذه الإيماءات تلقائيًا بواسطة مكونات مثل Modifier.scrollable و Modifier.transformable لتحسين الأداء مع لوحات اللمس.

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

لاختبار سلوك لوحة اللمس، توجد واجهات برمجة تطبيقات اختبار جديدة معperformTrackpadInput, والتي تسمح بالتحقق من صحة سلوك تطبيقاتك عند استخدامها مع لوحة اللمس. إذا كان لديك كاشفات إيماءات مخصصة، فتحقق من صحة السلوك عبر أنواع الإدخال المختلفة، بما في ذلك شاشات اللمس والفأرات ولوحات اللمس والأقلام، وتأكد من دعم عجلات تمرير الفأرة وإيماءات لوحة اللمس.

قبل وبعد.webp

الإعدادات الافتراضية لمضيف التركيب (وقت تشغيل Compose)

لقد قدمناHostDefaultProvider ،LocalHostDefaultProvider ،HostDefaultKey ، وViewTreeHostDefaultKey لتوفير خدمات على مستوى المضيف مباشرة من خلال compose-runtime. هذا يلغي الحاجة إلى اعتماد المكتبات على compose-ui للبحث، مما يدعم Kotlin Multiplatform بشكل أفضل. لربط هذه القيم بشجرة التركيب، يمكن لمؤلفي المكتبة استخدام compositionLocalWithHostDefaultOf لإنشاء CompositionLocal التي تحل القيم الافتراضية من المضيف.

معاينة الأغلفة

معاينة مخصصة في Android Studio هي ميزة جديدة تسمح لك بتحديد كيفية عرض محتويات معاينة Compose بالضبط.

من خلال تطبيق واجهة PreviewWrapperProvider وتطبيق التعليق التوضيحي الجديد @PreviewWrapper، يمكنك بسهولة إدخال منطق مخصص، مثل تطبيق Theme محدد. يمكن تطبيق التعليق التوضيحي على دالة معلّقة بـ @Composable و @Preview أو @MultiPreview، مما يوفر حلاً عامًا وسهل الاستخدام يعمل عبر ميزات المعاينة ويقلل بشكل كبير من التعليمات البرمجية المتكررة.

class ThemeWrapper: PreviewWrapperProvider {
    @Composable
    override fun Wrap(content: @Composable (() -> Unit)) {
        JetsnackTheme {
            content()
        }
    }
}


@PreviewWrapper(ThemeWrapper::class)
@Preview
@Composable
private fun ButtonPreview() {
    // JetsnackTheme in effect
    Button(onClick = {}) {
        Text(text = "Demo")
    }
}

عمليات الإتلاف والإزالة

  • كما أعلنّا في مشاركة المدونة حول الإصدار 1.10 من Compose، سنوقف نهائيًا Modifier.onFirstVisible(). غالبًا ما أدّى اسمها إلى حدوث مفاهيم خاطئة، لا سيما في التصاميم الكسولة، حيث يتم تشغيلها عدة مرات أثناء التمرير. ننصحك بالانتقال إلى Modifier.onVisibilityChanged()، ما يتيح تتبُّع حالات الظهور يدويًا بشكل أكثر دقة بما يتناسب مع متطلبات حالة الاستخدام المحدّدة.
  • تمت إزالة العلامة ComposeFoundationFlags.isTextFieldDpadNavigationEnabled لأنّ التنقّل باستخدام لوحة مفاتيح الاتجاهات في TextFields مفعّل دائمًا تلقائيًا. يضمن السلوك الجديد أنّ أحداث لوحة التحكّم الاتجاهية من وحدة التحكّم في الألعاب أو جهاز التحكّم عن بُعد الخاص بالتلفزيون تحرّك المؤشر أولاً في الاتجاه المحدّد. لا يمكن نقل التركيز إلى عنصر آخر إلا عندما يصل المؤشر إلى نهاية النص.

واجهات برمجة التطبيقات القادمة

في الإصدار القادم 1.12.0 من Compose، ستتم ترقية compileSdk إلى compileSdk 37، وسيتم تطبيق هذا الشرط على الإصدار 9 من "المكوّن الإضافي لنظام Gradle المتوافق مع Android" وجميع التطبيقات والمكتبات التي تعتمد على Compose. ننصحك بمتابعة أحدث الإصدارات، لأنّ Compose يهدف إلى اعتماد الإصدار compileSdks الجديد في أسرع وقت ممكن لتوفير إمكانية الوصول إلى أحدث ميزات Android. احرص على الاطّلاع على المستندات هنا للحصول على مزيد من المعلومات حول إصدار "مكوّن Android الإضافي لنظام Gradle" المتوافق مع مستويات واجهة برمجة التطبيقات المختلفة. 

في الإصدار 1.11.0 من Compose، تم طرح واجهات برمجة التطبيقات التالية كإصدار @Experimental، ونتطلّع إلى تلقّي ملاحظاتك أثناء استكشافها في تطبيقاتك. يُرجى العِلم أنّ @Experimental APIs يتم توفيرها لإجراء تقييم مبكر وتقديم ملاحظات، وقد تخضع لتغييرات كبيرة أو تتم إزالتها في الإصدارات المستقبلية.

الأنماط (ميزة تجريبية)

نقدّم واجهة برمجة تطبيقات تجريبية جديدة أساسية للتصميم. ‫Style API هي نموذج جديد لتخصيص العناصر المرئية للمكوّنات، والذي كان يتم تنفيذه في السابق باستخدام المعدِّلات. وهي مصمَّمة لإتاحة تخصيص أعمق وأسهل من خلال عرض مجموعة معايير التعلُّم من السمات القابلة للتصميم مع تصميم بسيط مستند إلى الحالة وعمليات انتقال متحركة. من خلال واجهة برمجة التطبيقات الجديدة هذه، بدأنا نلاحظ تحسّنًا ملحوظًا في الأداء. نخطّط لاستخدام "الأنماط" في مكوّنات Material عند استقرار Style API.

مثال أساسي على إلغاء خلفية نمط الحالة المضغوطة:

@Composable
fun LoginButton(modifier: Modifier = Modifier) {
    Button(
        onClick = {
            // Login logic
        },
        modifier = modifier,
        style = {
            background(
                Brush.linearGradient(
                    listOf(lightPurple, lightBlue)
                )
            )
            width(75.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            externalPadding(16.dp)

            pressed {
                background(
                    Brush.linearGradient(
                        listOf(Color.Magenta, Color.Red)
                    )
                )
            }
        }
    ){
        Text(
            text = "Login",
        )
    }
}
styles.webp

يمكنك الاطّلاع على المستندات والإبلاغ عن أي أخطاء هنا.

MediaQuery (تجريبي)

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

بفضل دعم مجموعة واسعة من الإشارات البيئية - بدءًا من إمكانيات الجهاز مثل أنواع لوحة المفاتيح ودقة المؤشر، وصولًا إلى الحالات السياقية مثل حجم النافذة ووضعيتها - يمكنك بناء تجارب تفاعلية للغاية. الأداء جزء لا يتجزأ منderivedMediaQuery للتعامل مع التحديثات عالية التردد، في حين أن القدرة على تجاوز النطاقات تجعل الاختبار والمعاينات سلسة عبر تكوينات الأجهزة. في السابق، للوصول إلى خصائص معينة للجهاز - مثل ما إذا كان الجهاز في وضع tabletop mode - كنت ستحتاج إلى كتابة الكثير من التعليمات البرمجية المتكررة للقيام بذلك: 

@Composable
fun isTabletopPosture(
    context: Context = LocalContext.current
): Boolean {
    val windowLayoutInfo by
        WindowInfoTracker
            .getOrCreate(context)
            .windowLayoutInfo(context)
            .collectAsStateWithLifecycle(null)

    return windowLayoutInfo.displayFeatures.any { displayFeature ->
        displayFeature is FoldingFeature &&
            displayFeature.state == FoldingFeature.State.HALF_OPENED &&
            displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
    }
}

@Composable
fun VideoPlayer() {
    if(isTabletopPosture()) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

الآن، باستخدام UIMediaQuery، يمكنك إضافة الصيغة mediaQuery للاستعلام عن خصائص الجهاز، مثل ما إذا كان الجهاز في وضع سطح الطاولة:

@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun VideoPlayer() {
    if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

راجع الوثائق وقم بالإبلاغ عن أي أخطاء هنا.

الشبكة (تجريبية)

Gridهي واجهة برمجة تطبيقات جديدة وقوية لبناء تخطيطات ثنائية الأبعاد معقدة في Jetpack Compose. بينما يعتبر Row و Column رائعين للتصميمات الخطية، فإن Grid يمنحك التحكم الهيكلي اللازم لهندسة مستوى الشاشة والمكونات المعقدة دون الحاجة إلى قائمة قابلة للتمرير. Grid يسمح لك بتحديد تخطيطك باستخدام المسارات والفجوات والخلايا، مما يوفر خيارات تحجيم مألوفة مثل Dp والنسب المئوية وأحجام المحتوى الجوهرية ووحدات "Fr" المرنة. 

@OptIn(ExperimentalGridApi::class)
@Composable
fun GridExample() {
    Grid(
        config = {
            repeat(4) { column(0.25f) }
            repeat(2) { row(0.5f) }
            gap(16.dp)
        }
    ) {
        Card1(modifier = Modifier.gridItem(rowSpan = 2)
        Card2(modifier = Modifier.gridItem(colmnSpan = 3)
        Card3(modifier = Modifier.gridItem(columnSpan = 2)
        Card4()
    }
}

يمكنك وضع العناصر تلقائيًا أو توزيعها بشكل صريح عبر صفوف وأعمدة متعددة لتحقيق الدقة. والأفضل من ذلك كله، أنه قابل للتكيف بدرجة عالية - يمكنك إعادة تكوين مسارات الشبكة وامتداداتها ديناميكيًا للاستجابة لحالات الجهاز مثل وضع سطح المكتب أو تغييرات الاتجاه، مما يضمن أن تبدو واجهة المستخدم الخاصة بك رائعة عبر عوامل الشكل المختلفة.

Grid.gif

راجع الوثائق وقم بالإبلاغ عن أي أخطاء هنا

FlexBox (تجريبي)

FlexBox عبارة عن حاوية تخطيط مصممة لواجهات المستخدم عالية الأداء والمتكيفة. يتولى النظام إدارة أحجام العناصر وتوزيع المساحة بناءً على أبعاد الحاويات المتاحة.يتولى هذا النظام مهامًا معقدة مثل التغليف (wrap) ومحاذاة العناصر متعددة المحاور (justifyContent, alignItems, alignContent). كما يسمح للعناصر بالتمدد (grow) أو الانكماش (shrink) لملء الحاوية. 

@OptIn(ExperimentalFlexBoxApi::class)
fun FlexBoxWrapping(){
    FlexBox(
        config = {
            wrap(FlexWrap.Wrap)
            gap(8.dp)
        }
    ) {
        RedRoundedBox()
        BlueRoundedBox()
        GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
        OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
        PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
    }
}
AnimationGif.gif

راجع الوثائق وقم بالإبلاغ عن أي أخطاء هنا.

تنفيذ جديد لجدول الفتحات (تجريبي)

لقد قدمنا ​​تطبيقًا جديدًا لـ SlotTable، وهو معطل افتراضيًا في هذا الإصدار.SlotTable هي بنية البيانات الداخلية التي يستخدمها وقت تشغيل Compose لتتبع حالة التسلسل الهرمي للتكوين الخاص بك، وتتبع عمليات الإبطال/إعادة التكوين، وتخزين القيم المحفوظة، وتتبع جميع البيانات الوصفية للتكوين في وقت التشغيل. تم تصميم هذا التطبيق الجديد لتحسين الأداء، وخاصة فيما يتعلق بالتعديلات العشوائية.

لتجربة الجديدSlotTable ، يُمكَِنComposeRuntimeFlags.isLinkBufferComposerEnabled

ابدأ الترميز اليوم.

مع توفّر العديد من واجهات برمجة التطبيقات الجديدة والمثيرة للاهتمام في Jetpack Compose، والمزيد منها في الطريق إليك، لم يكن هناك وقت أفضل من الآن للانتقال إلى Jetpack Compose.  وكالعادة، يهمّنا تلقّي ملاحظاتك وطلباتك بشأن الميزات (خاصةً @Experimentalتلك التي لا تزال قيد التطوير) — يُرجى إرسالها هنا. نتمنّى لك تجربة ممتعة في تأليف الأغاني.

من تأليف:
متابعة القراءة