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

ما الجديد في إصدار Jetpack Compose لشهر أغسطس 2026؟

مدّة القراءة: 5 دقائق
عرض الملف الشخصي لـ "نيك بوتشر"
Nick Butcher مدير منتجات

أصبح إصدار Jetpack Compose لشهر أغسطس 2026 ثابتًا اليوم. يتضمّن هذا الإصدار الإصدار 1.12 من وحدات Compose الأساسية (راجِع خريطة BOM الكاملة)، ويقدّم واجهات برمجة تطبيقات مرئية غنية، مثل Mesh Gradients ودعم Wide Color Gamut (WCG)، وميزات التنسيق الهيكلي، مثل المناطق المسماة في Grid، والتكامل السلس مع Credential Manager من Android، وتحسينات كبيرة في الاختبار والأداء.

لتعديل مشروعك إلى الإصدار الحالي، عليك ترقية إصدار Compose BOM إلى 2026.08.00:

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

تغييرات قد تؤدي إلى أعطال

  • AGP وCompile SDK: يغيّر Compose 1.12 إعداد compileSdk إلى واجهة برمجة التطبيقات 37، ما يتطلّب الحد الأدنى من AGP 9.1.2. للتذكير، سيستهدف Compose دائمًا أحدث إصدار من compileSdk. يمكنك الاطّلاع على مزيد من المعلومات عن هذا التغيير هنا.
  • Modifier.onFirstVisible() تم إيقافها نهائيًا: عليك الانتقال إلى Modifier.onVisibilityChanged()، التي توفّر تتبُّعًا أكثر دقة لعتبة الظهور.

الرسومات

Mesh Gradients

يقدّم Compose 1.12 السمة MeshGradientPainter لمساعدتك في إنشاء تدرّجات ألوان متعددة النقاط وعضوية.

meshGradient.gif
val rows = 1
val columns = 1

val gradientPainter = remember {
    MeshGradientPainter(rows, columns) {
        // Parameters: row, column, position, color
        setVertex(0, 0, Offset(0f, 0f), Color.Red)     // Top-Left
        setVertex(0, 1, Offset(1f, 0f), Color.Blue)    // Top-Right
        setVertex(1, 0, Offset(0f, 1f), Color.Green)   // Bottom-Left
        setVertex(1, 1, Offset(1f, 1f), Color.Yellow)  // Bottom-Right
    }
}

Box(
    modifier = modifier
        .aspectRatio(16/9f)
        .fillMaxWidth()
        .paint(gradientPainter)
)

لمزيد من المعلومات والأمثلة، يُرجى الاطّلاع على المستندات.

Wide Color Gamut ودعم HDR

توفّر الشاشات الحديثة دقة ألوان محسّنة ونطاقًا ديناميكيًا أعلى. في Compose 1.12، تم تفعيل الدعم الكامل لخط الأنابيب Wide Color Gamut (P3) وعرض HDR في جميع رسومات Compose والطلاء والتظليل. يتم الاحتفاظ بالألوان المحدّدة في مساحات الألوان غير sRGB (مثل Display P3) حتى عرض النظام الأساسي بدون حصر الألوان. سيتم الرجوع بأمان إلى sRGB إذا كانت الألوان تستخدم مساحة ألوان غير متوافقة (مثل CieXyz أو CieLab أو Oklab)، أو إذا كانت تعتمد على مساحة ألوان على إصدار غير متوافق من Android (مثل Bt2020Hlg على Android 13 والإصدارات الأقدم)، أو إذا كان التطبيق قيد التشغيل على Android 9 (واجهة برمجة التطبيقات 28) والإصدارات الأقدم.

التغييرات البارزة الأخرى:

  • LayerOutsets تمت إضافته إلى GraphicsLayer وModifier.graphicsLayer، ويمكنك استخدامه لزيادة الحدود المرئية للطبقة خارج حجمها المقاس. يمكنك تطبيق LayerOutsets لتجنُّب السلوك الضمني clipToBounds عند ترقية الطبقة إلى مخزن مؤقت خارج الشاشة.

الأنماط

في Google I/O، شاركنا رؤيتنا المبكرة لواجهة برمجة التطبيقات Styles API في Compose، وهي طريقة موحّدة وفعّالة لتصميم المكوّنات. ومنذ ذلك الحين، واصلنا إنشاء البنية الأساسية لضمان سلامة الأنواع الصارمة والدقة المتوقّعة، ولدعم إنشاء أنظمة تصميم مخصّصة. 

لضمان دقة هذه الطبقة الأساسية، ستبقى واجهة برمجة التطبيقات تجريبية، ويمكنك توقُّع تغييرات قد تؤدي إلى أعطال. 

تحسينات وقت التشغيل

تجاوز SideEffect الذي يستند إلى مفتاح

SideEffect تتوافق الآن مع وسيطات المفاتيح، ما يتيح لك تشغيل تأثيرات جانبية لمرة واحدة كلما تغيّرت مفاتيح معيّنة. يمكن أن يؤدي ذلك إلى أداء أفضل مقارنةً باستخدام LaunchedEffect أو DisposableEffect عندما لا تحتاج إلى الروتين الفرعي أو كتلة الإزالة. تكون SideEffect أسرع بنسبة تصل إلى% 90 من LaunchedEffect وأسرع بنسبة% 20 تقريبًا من DisposableEffect. يُرجى العِلم أنّ SideEffect تشغّل تأثيرها قبل DisposableEffect وLaunchedEffect، لذا يجب توخي الحذر عند نقل التأثيرات الحالية إلى واجهة برمجة التطبيقات هذه، خاصةً بالنسبة إلى LaunchedEffects التي تعتمد على إرسالها للبدء بعد اكتمال الإطار الحالي. 

@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
    SideEffect(key1 = userId, key2 = screenName) {
        analytics.logScreenView(userId, screenName)
    }
}

الصور المتحركة

عمليات الانتقال التفاعلية ذات المرحلتَين

  • مكوّنات جديدة قابلة للإنشاءDeferredAnimatedContent وDeferredAnimatedVisibility تسمح بإنشاء عمليات انتقال مبهجة ذات مرحلتَين، مثلاً لتتبُّع إيماءة الرجوع التنبؤية.
  • التحكّم اليدوي في الصور المتحركة: أثناء المرحلة المؤجّلة من عملية الانتقال، يمكن الآن معالجة الخصائص المتحركة (مثل المقياس أو الإزاحة) يدويًا في الوقت الفعلي (مثلاً، تتبُّع إيماءة التمرير السريع).
  • عملية نقل سلسة: بعد انتهاء المرحلة المؤجّلة، يتولّى محرّك الانتقال المسؤولية ويُجري عملية نقل سلسة، بما في ذلك نقل السرعة، إلى عملية الانتقال التلقائية.
  • دعم العناصر المشترَكة: يتحكّم الإعداد الجديد permitTransformDuringDeferredTransition في SharedContentConfig في ما إذا كانت العناصر المشترَكة تتحوّل مرئيًا مع الحاويات الرئيسية أثناء مرحلة الانتقال المؤجّلة.
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)

if (predictiveBackInProgress) {
    state.defer(targetScreen)
} else {
    state.animateTo(targetScreen)
}

transition.DeferredAnimatedContent(
    targetState = targetScreen,
    mutableTransformSpec = {
       MutableContentTransform {
           // Manually manipulate properties during the deferred phase
           initialContentTransform { scale = swipeProgress }
       }
    }
) { screen ->
    ScreenContent(screen)
}

في ما يلي عرضان توضيحيان لحالتَي استخدام يتم فيهما نقل صورة متحركة مستندة إلى إيماءة إلى صورة متحركة يتم تشغيلها:

colorCards.gif

النصوص والإدخال وعمليات التكامل مع النظام الأساسي

تنسيق النصوص القابلة للتعديل

توفر واجهات برمجة التطبيقات الجديدة تنسيق نصوص منسقة للنصوص القابلة للتعديل في BasicTextField. يمكنك الآن تطبيق تنسيق الأحرف والفقرات المضمّنة ومعالجتها آليًا باستخدام SpanStyle و ParagraphStyle من خلال الطريقة الجديدة addStyle() داخل نطاق TextFieldBuffer (مثل داخل textFieldState.edit { ... } أو InputTransformation). بالإضافة إلى ذلك، توفّر TextFieldBuffer واجهات برمجة التطبيقات getSpanStyles() و getParagraphStyles() التي تعرض كائنات TrackedRange، ما يتيح لك قراءة الأنماط المطبّقة أو تعديلها أو إزالتها. لاستكمال إنشاء التنسيق، يعرض TextFieldState الآن خاصية textStyles للقراءة فقط من أجل طلب الأنماط النشطة في النطاقات، بينما توفّر TextFieldBuffer السمة originalTextStyles لفحص حالة التنسيق قبل إجراء تعديل. يتم الاحتفاظ بتنسيق النص والتعليقات التوضيحية المخصّصة عند إجراء تغييرات في الإعدادات.

val state = rememberTextFieldState("Formatted text in Compose 1.12")

// Apply bold and color styles to a range of text
state.edit {
    addStyle(
        SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
        start = 0,
        end = 9
    )
}

// Query active styles from TextFieldState
val currentStyles = state.textStyles

تحديد النص

توفر واجهة برمجة التطبيقات الجديدة SelectionState إمكانية التحكم آليًا في تحديد النص داخل SelectionContainer ومراقبة ذلك. يؤدي رفع مستوى كائن SelectionState من خلال rememberSelectionState() وتمريره إلى SelectionContainer إلى عرض selectedTexts كقائمة تفاعلية من AnnotatedStrings وتوفير طرق، مثل selectAll() وclear() وselect(TextRange) وextendSelectionByWord().

بالإضافة إلى ذلك، استخدِم getSelectableTexts() لاسترداد جميع عناصر النص القابلة للتحديد بترتيب التنسيق وحدِّد النص في المكوّنات القابلة للإنشاء في SelectionContainer باستخدام نطاق عام. 

@Composable
fun ProgrammaticSelectionExample() {
    val selectionState = rememberSelectionState()

    Column {
        Button(
            onClick = { selectionState.selectAll() },
            modifier = Modifier.disableSelectionClearOnTap()
        ) {
            Text("Select All")
        }

        SelectionContainer(state = selectionState) {
            Text("Text content to be selected programmatically.")
        }
    }
}

التكامل مع Credential Manager

تتكامل حقول نصوص Compose الآن بشكلٍ أصلي مع Credential Manager من Android (واجهة برمجة التطبيقات 34 والإصدارات الأحدث) من خلال إطار عمل الملء التلقائي (تتعامل androidx.credentials library مع الإصدارات الأقدم من واجهة برمجة التطبيقات 34). من خلال إرفاق السمة الدلالية الجديدة credentialRequest مع CredentialRequestData، يمكن أن تطلب إدخالات النصوص مفاتيح المرور أو بيانات الاعتماد المحفوظة أو طلبات تسجيل الدخول مباشرةً ضمن مسار بيانات أدخلها المستخدم.

@Composable
fun LoginField(textFieldState: TextFieldState) {
    val credentialData = remember {
        CredentialRequestData(
            // Specify Credential Manager request options
        )
    }

    BasicTextField(
        state = textFieldState,
        modifier = Modifier.semantics {
            credentialRequest = credentialData
        }
    )
}

التغييرات البارزة الأخرى:

  • تتوافق الخطوط القابلة للتنزيل مع إعدادات تنويع الخطوط.
  • تم تفعيل التمرير التلقائي عند سحب تحديد النص خارج إطار العرض في SelectionContainer.
  • تمت إضافة إمكانية تشغيل أصوات التفاعل التلقائية (النقر والتنقّل باستخدام التركيز) إلى مكوّنات Compose، مع مكوّن جديد قابل للإنشاء SoundEffectOnInteraction للسماح بإيقاف هذه الميزة. يُرجى العِلم أنّه نتيجةً لهذا التغيير، يجب الآن استدعاء مستمعي النقر الدلالي من سلسلة التعليمات الرئيسية، ما قد يؤثر في عدد صغير من حالات الاختبار.
  • KeyboardType تتضمّن الآن Date وTime وDateTime وSignedDecimal.
  • BasicSecureTextField يستخدم الآن TextObfuscationMode.System تلقائيًا، بينما يعمل RevealLastTyped كإعداد مطلق لتجاوز الإعدادات.

تحسينات التنسيق

المناطق المسماة في تنسيق Grid

أصبح إنشاء تنسيقات ثنائية الأبعاد معقدة أسهل الآن باستخدام المناطق المسماة في مكوّن @Experimental Grid. بدلاً من إدارة أرقام أعمدة الصفوف والفهارس في العناصر، يمكنك تحديد مناطق دلالية في GridConfigurationScope ووضع المكوّنات القابلة للإنشاء حسب اسم المنطقة.

@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
    Grid(
        config = {
            area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
            area("sidebar", row = 1, column = 0)
            area("content", row = 1, column = 1)
            gap(16.dp)
        }
    ) {
        HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
        NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
        MainContentView(modifier = Modifier.gridItem(areaId = "content"))
    }
}

لمزيد من المعلومات، يُرجى الاطّلاع على المستندات.

الأداء

كما هو الحال مع كل إصدار، نواصل الاستثمار في أداء Compose لضمان مساعدتك في إنشاء تطبيقات جميلة وفعّالة. في هذا الإصدار، ركّزنا على تحسين أداء بدء التشغيل، ونلاحظ الآن وقتًا للعرض الأولي (الوقت الذي يستغرقه التطبيق لإنتاج إطاره الأول) يضاهي وقت العرض الأولي في Views في نتائجنا المعيارية.

timetoinitialdisplay@2x _v2.png

ترقيات الاختبار والأدوات

مزامنة الاختبار

يقدّم Compose 1.12 واجهات برمجة تطبيقات جديدة للاختبار مصمّمة لتقليل أوقات تنفيذ الاختبار وإزالة عدم الثبات أثناء أخذ عينات الحالة:

  • hasPendingWork: تتحقّق هذه الطريقة بشكل غير مباشر مما إذا كانت واجهة المستخدم تتضمّن عملًا معلّقًا بدون تقدّم الساعة، ما يجعلها مثالية لحلقات الصور المتحركة اليدوية.
  • runWithoutImplicitWait: توقِف هذه الطريقة مؤقتًا المزامنة الضمنية عند الانتقال بين إطارات الساعة اليدوية (مثل اختبارات الصور المتحركة).
@Test
fun testAnimationStateFast() {

composeTestRule.mainClock.autoAdvance = false
    
    while (composeTestRule.hasPendingWork()) {
        composeTestRule.mainClock.advanceTimeByFrame()
        composeTestRule.waitForIdle()
        
        composeTestRule.runOnUiThread {
            composeTestRule.runWithoutImplicitWait {
                // This is most effective when querying multiple nodes in a single frame. 
                // It prevents the redundant synchronization overhead that would 
                // otherwise occur on every individual query.
                val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
                val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
                
                assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
            }
        }
    }
}

التغييرات البارزة الأخرى:

  • تتيح لك واجهة برمجة التطبيقات captureToImage الآن التقاط نافذة منبثقة أو مربّع حوار مع نقطة الارتساء في صورة نقطية واحدة.
  • تمت إضافة onRootWithViewInteraction لتحديد نطاق عمليات البحث الدلالية في Compose في Android Views معيّنة. يسهّل ذلك اختبار واجهات المستخدم المختلطة، مثل RecyclerViews، بدون الحاجة إلى علامات اختبار فريدة في رمز الإنتاج.
  • @PreviewWrapper يمكن الآن تطبيق التعليقات التوضيحية على فئات @MultiPreview المخصّصة، ما يتيح إعدادات معاينة قابلة لإعادة الاستخدام (مثل المظاهر المخصّصة) في مكوّنات متعدّدة.

نتمنّى لك تجربة ممتعة في إنشاء المحتوى باستخدام Compose.

يسهّل Compose 1.12 تطوير التطبيقات ويجعله أكثر تعبيرًا من أي وقت مضى، وذلك بفضل Mesh Gradients ودعم Wide Color Gamut والخطوط المتغيّرة القابلة للتنزيل والتكامل مع Credential Manager وأدوات الاختبار الأسرع. وكالعادة، نقدّر ملاحظاتك، لذا يُرجى مشاركة ملاحظاتك حول هذه التغييرات أو ما تريد رؤيته بعد ذلك في أداة تتبُّع المشاكل. نتمنّى لك تجربة ممتعة في إنشاء المحتوى باستخدام Compose.

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