أصبح إصدار كانون الأول (ديسمبر) 2025 من Jetpack Compose ثابتًا اليوم. يحتوي هذا الإصدار على الإصدار 1.10 من وحدات Compose الأساسية والإصدار 1.4 من Material 3 (راجِع عملية الربط الكاملة بين حزمة إدارة الفواتير)، ما يضيف ميزات جديدة وتحسينات كبيرة على مستوى الأداء.
لاستخدام الإصدار الحالي، عليك ترقية إصدار Compose BOM إلى 2025.12.00:
implementation(platform("androidx.compose:compose-bom:2025.12.00"))تحسينات على الأداء
ندرك أنّ أداء وقت التشغيل لتطبيقك مهم للغاية بالنسبة إليك وإلى المستخدمين، لذا كان الأداء من أهم أولويات فريق Compose. يتضمّن هذا الإصدار عددًا من التحسينات، ويمكنك الحصول عليها جميعًا من خلال الترقية إلى أحدث إصدار. توضّح مقاييس الأداء الداخلية للتمرير أنّ Compose يتطابق الآن مع الأداء الذي ستحصل عليه في حال استخدام Views:
مقياس أداء التمرير الذي يقارن بين Views وJetpack Compose في إصدارات مختلفة من Compose
التركيب القابل للإيقاف المؤقت في الجلب المسبق الكسول
تم الآن تفعيل ميزة "التركيب القابل للإيقاف المؤقت" في "الجلب المُسبَق الكسول" تلقائيًا. هذا تغيير أساسي في طريقة عمل جداول التشغيل في وقت التشغيل في Compose، وهو مصمَّم للحدّ بشكل كبير من إيقاف مؤقت لعرض واجهة المستخدم أثناء أعباء العمل الكبيرة في واجهة المستخدم.
في السابق، كان يجب إكمال أي مقطوعة موسيقية بعد بدء تشغيلها. إذا كان التكوين معقّدًا، قد يؤدي ذلك إلى حظر سلسلة التعليمات الرئيسية لمدة أطول من إطار واحد، ما يؤدي إلى تجمُّد واجهة المستخدم. باستخدام ميزة "التركيب القابل للإيقاف المؤقت"، يمكن لوقت التشغيل الآن "إيقاف" عمله مؤقتًا إذا كان الوقت المتاح له سينتهي، واستئناف العمل في اللقطة التالية. ويكون هذا الإجراء فعّالاً بشكل خاص عند استخدامه مع ميزة "الجلب المسبق للتنسيق الكسول" لإعداد اللقطات مسبقًا. تُعدّ واجهات برمجة التطبيقات CacheWindow الخاصة بالتنسيق Lazy التي تم طرحها في Compose 1.9 طريقة رائعة لجلب المزيد من المحتوى مسبقًا والاستفادة من التكوين القابل للإيقاف المؤقت من أجل تقديم أداء أكثر سلاسة لواجهة المستخدم.
تساعد ميزة "التكوين القابل للإيقاف المؤقت" مع ميزة "الجلب المسبق الكسول" في تقليل إيقاف مؤقت لعرض واجهة المستخدم
لقد حسّنّا أيضًا الأداء في أماكن أخرى، من خلال إجراء تحسينات على Modifier.onPlaced وModifier.onVisibilityChanged وعناصر التعديل الأخرى. سنواصل الاستثمار في تحسين أداء ميزة "إنشاء أغنية".
الميزات الجديدة
الاحتفاظ
توفّر Compose عددًا من واجهات برمجة التطبيقات للاحتفاظ بالحالة وإدارتها على مستوى دورات حياة مختلفة، على سبيل المثال، remember تحتفظ بالحالة على مستوى عمليات الإنشاء، وrememberSavable/rememberSerializable للاحتفاظ بها على مستوى إعادة إنشاء النشاط أو العملية. retain هي واجهة برمجة تطبيقات جديدة تقع بين واجهات برمجة التطبيقات هذه، ما يتيح لك الاحتفاظ بالقيم عند إجراء تغييرات في الإعدادات بدون تسلسلها، ولكن ليس عند إيقاف العملية نهائيًا. بما أنّ retain لا ينفّذ تسلسلاً لحالتك، يمكنك الاحتفاظ بعناصر مثل تعابير lambda وعمليات نقل البيانات والكائنات الكبيرة مثل الصور النقطية التي لا يمكن تنفيذ تسلسل لها بسهولة. على سبيل المثال، يمكنك استخدام retain لإدارة مشغّل وسائط (مثل ExoPlayer) لضمان عدم توقّف تشغيل الوسائط بسبب تغيير في الإعدادات.
@Composable
fun MediaPlayer() {
val applicationContext = LocalContext.current.applicationContext
val exoPlayer = retain { ExoPlayer.Builder(applicationContext).apply { ... }.build() }
...
}نودّ أن نتقدّم بالشكر إلى منتدى AndroidDev (خاصةً فريق Circuit) الذين ساهموا في تصميم هذه الميزة.
المادة 1.4
يضيف الإصدار 1.4.0 من مكتبة material3 عددًا من المكوّنات والتحسينات الجديدة:
- توفّر
TextFieldالآن إصدارًا تجريبيًا يعتمد علىTextFieldState، ما يوفّر طريقة أكثر فعالية لإدارة حالة النص. بالإضافة إلى ذلك، تتوفّر الآن صيغ جديدة منSecureTextFieldوOutlinedSecureTextField. يتوافق العنصر القابل للإنشاءTextالآن مع سلوك autoSize. - يتوفّر الآن
HorizontalCenteredHeroCarouselنوع جديد لمكوّن لوحة العرض الدوّارة. - تتيح أداة اختيار
TimePickerالآن التبديل بين وضعَي أداة الاختيار والإدخال. - يساعد مقبض السحب العمودي المستخدمين على تغيير حجم و/أو موضع اللوحة التكيّفية.
لوحة عرض دوّارة أفقية في وسط الصفحة
يُرجى العِلم أنّه سيتم مواصلة تطوير واجهات برمجة التطبيقات Material 3 Expressive في الإصدارات الأولية من مكتبة material3. لمزيد من المعلومات، يمكنك مشاهدة هذه المحاضرة الأخيرة:
ميزات جديدة للصور المتحركة
نواصل توسيع نطاق واجهات برمجة التطبيقات الخاصة بالرسوم المتحركة، بما في ذلك التعديلات اللازمة لتخصيص الرسوم المتحركة للعناصر المشترَكة.
العناصر المشترَكة الديناميكية
بشكلٍ تلقائي، تحاول الحركتان sharedElement() وsharedBounds() تحريك
تتغير التنسيقات كلما تم العثور على مفتاح مطابق في حالة الهدف. ومع ذلك، قد تحتاج إلى إيقاف هذه الصورة المتحركة بشكل ديناميكي استنادًا إلى شروط معيّنة، مثل اتجاه التنقّل أو حالة واجهة المستخدم الحالية.
للتحكّم في ما إذا كان سيحدث انتقال العنصر المشترَك، يمكنك الآن تخصيص SharedContentConfig الذي تم تمريره إلى rememberSharedContentState(). تحدّد السمة isEnabled ما إذا كان العنصر المشترَك نشطًا.
SharedTransitionLayout {
val transition = updateTransition(currentState)
transition.AnimatedContent { targetState ->
// Create the configuration that depends on state changing.
fun animationConfig() : SharedTransitionScope.SharedContentConfig {
return object : SharedTransitionScope.SharedContentConfig {
override val SharedTransitionScope.SharedContentState.isEnabled: Boolean
get() =
// determine whether to perform a shared element transition
}
}
}يمكنك الاطّلاع على المستندات لمزيد من المعلومات.
Modifier.skipToLookaheadPosition()
تمت إضافة معدِّل جديد، Modifier.skipToLookaheadPosition()، في هذا الإصدار، وهو يحافظ على الموضع النهائي لعنصر قابل للإنشاء عند تنفيذ حركات العناصر المشترَكة. يتيح ذلك تنفيذ انتقالات مثل الصورة المتحركة من النوع "كشف"، كما يمكن ملاحظة ذلك في عيّنة Androidify مع الكشف التدريجي عن الكاميرا. يمكنك الاطّلاع على نصيحة الفيديو هنا للحصول على مزيد من المعلومات:
السرعة الأوّلية في عمليات الانتقال بين العناصر المشتركة
يضيف هذا الإصدار واجهة برمجة تطبيقات جديدة لنقل العناصر المشترَكة، prepareTransitionWithInitialVelocity، تتيح لك تمرير سرعة أولية (مثل سرعة الإيماءة) إلى عملية نقل عنصر مشترَك:
Modifier.fillMaxSize()
.draggable2D(
rememberDraggable2DState { offset += it },
onDragStopped = { velocity ->
// Set up the initial velocity for the upcoming shared element
// transition.
sharedContentStateForDraggableCat
?.prepareTransitionWithInitialVelocity(velocity)
showDetails = false
},
)
انتقال عنصر مشترك يبدأ بسرعة أولية من إيماءة
عمليات الانتقال المخفية
تحدّد EnterTransition وExitTransition طريقة ظهور الدالة المركّبة AnimatedVisibility/AnimatedContent أو اختفائها. يتيح لك خيار التمويه التجريبي الجديد تحديد لون لتمويه المحتوى أو تغطيته، مثلاً، يمكنك إضافة طبقة سوداء شبه شفافة تتلاشى تدريجيًا فوق المحتوى أو العكس:
محتوى متحرك محجوب – لاحظ الحجاب شبه الشفاف (أو الشاشة الشفافة) فوق محتوى الشبكة أثناء الحركة
AnimatedContent(
targetState = page,
modifier = Modifier.fillMaxSize().weight(1f),
transitionSpec = {
if (targetState > initialState) {
(slideInHorizontally { it } togetherWith
slideOutHorizontally { -it / 2 } + veilOut(targetColor = veilColor))
} else {
slideInHorizontally { -it / 2 } +
unveilIn(initialColor = veilColor) togetherWith slideOutHorizontally { it }
}
},
) { targetPage ->
...
}
التغييرات القادمة
إيقاف Modifier.onFirstVisible نهائيًا
قدّمت الإصدار 1.9 من Compose Modifier.onVisibilityChanged وModifier.onFirstVisible. بعد مراجعة ملاحظاتك، تبيّن لنا أنّه لا يمكن تنفيذ عقد Modifier.onFirstVisible بشكل حتمي، وتحديدًا عندما يصبح العنصر مرئيًا لأول مرة. على سبيل المثال، قد تتخلص Lazy Layout من العناصر التي يتم تمريرها خارج إطار العرض، ثم تعيد إنشاءها إذا تم تمريرها مرة أخرى إلى إطار العرض. في هذه الحالة، سيتم تشغيل onFirstVisible مرة أخرى، لأنّها عنصر تم إنشاؤه حديثًا. سيحدث سلوك مشابه أيضًا عند الرجوع إلى شاشة تمت زيارتها سابقًا وتحتوي على onFirstVisible. لذلك، قرّرنا إيقاف هذا المعدِّل نهائيًا في إصدار Compose التالي (1.11) وننصحك بالانتقال إلى onVisibilityChanged. لمزيد من المعلومات، يُرجى الاطّلاع على المستندات.
إرسال الروتينات المشتركة في الاختبارات
نخطّط لتغيير عملية إرسال الروتينات الفرعية في الاختبارات لتحسين موثوقية الاختبارات ورصد المزيد من المشاكل. في الوقت الحالي، تستخدم الاختبارات UnconfinedTestDispatcher، وهو يختلف عن سلوك الإصدار العلني؛ على سبيل المثال، قد يتم تنفيذ التأثيرات على الفور بدلاً من وضعها في قائمة الانتظار. في إصدار مستقبلي، نخطّط لطرح واجهة برمجة تطبيقات جديدة تستخدم StandardTestDispatcher تلقائيًا لمطابقة سلوكيات الإنتاج. يمكنك تجربة السلوك الجديد الآن في الإصدار 1.10:
@get:Rule // also createAndroidComposeRule, createEmptyComposeRule val rule = createComposeRule(effectContext = StandardTestDispatcher())
سيؤدي استخدام StandardTestDispatcher إلى وضع المهام في قائمة الانتظار، لذا عليك استخدام آليات المزامنة، مثل composeTestRule.waitForIdle() أو composeTestRule.runOnIdle(). إذا كان الاختبار يستخدم runTest، عليك التأكّد من أنّ runTest وقاعدة Compose تستخدمان مثيل StandardTestDispatcher نفسه للمزامنة.
// 1. Create a SINGLE dispatcher instance
val testDispatcher = StandardTestDispatcher()
// 2. Pass it to your Compose rule
@get:Rule
val composeRule = createComposeRule(effectContext = testDispatcher)
@Test
// 3. Pass the *SAME INSTANCE* to runTest
fun myTest() = runTest(testDispatcher) {
composeRule.setContent { /* ... */ }
}
الأدوات
تستحق واجهات برمجة التطبيقات الرائعة أدوات رائعة، وقد أضفنا مؤخرًا عددًا من الأدوات إلى استوديو Android لمطوّري Compose:
- تحويل واجهة المستخدم: يمكنك تكرار تصاميمك من خلال النقر بزر الماوس الأيمن على
@Preview، واختيار "تحويل واجهة المستخدم"، ثم وصف التغيير باللغة الطبيعية. - إنشاء
@Preview: انقر بزر الماوس الأيمن على دالة مركّبة واختَر Gemini > إنشاء معاينة [اسم الدالة المركّبة] . - تخصيص رموز Material Symbols من خلال توفير دعم جديد لأشكال الرموز في معالج Vector Asset.
- إنشاء رمز من لقطة شاشة أو اسأل Gemini مطابقة واجهة المستخدم الحالية مع صورة مستهدَفة يمكن دمج ذلك مع دعم MCP عن بُعد، مثلاً للاتصال بملف Figma وإنشاء واجهة مستخدم Compose من التصاميم.
- تُجري عمليات التدقيق في حلّ المشاكل المتعلّقة بجودة واجهة المستخدم تدقيقًا لواجهة المستخدم بحثًا عن المشاكل الشائعة، مثل مشاكل سهولة الاستخدام، ثم تقترح حلولاً.
لمشاهدة هذه الأدوات أثناء العمل، شاهِد هذا العرض التوضيحي الأخير:
Happy Composing
نواصل الاستثمار في Jetpack Compose لتزويدك بواجهات برمجة التطبيقات والأدوات التي تحتاج إليها لإنشاء واجهات مستخدم رائعة وغنية بالميزات. نحن نقدّر ملاحظاتك، لذا يُرجى مشاركتها معنا بشأن هذه التغييرات أو الميزات التي تريد أن نطلقها في أداة تتبُّع المشاكل.
متابعة القراءة
-
أخبار المنتجات
منذ إطلاق Jetpack Compose قبل 5 سنوات تقريبًا، استثمرنا في توفير جميع الميزات والأداء والأدوات التي تحتاج إليها لإنشاء واجهات مستخدم رائعة على مجموعة متنوعة من أجهزة Android.
Nick Butcher • مدة القراءة: دقيقتان
-
أخبار المنتجات
يسرّنا الإعلان عن أنّنا أتحنا رسميًا استخدام Unreal Engine و Godot على Android XR. نحن بصدد إطلاق أداتَين جديدتَين مصمّمتَين لتعزيز إنتاجيتك وإتاحة إمكانات جديدة للواقع الممتد، وهما Android XR Engine Hub وAndroid XR Interaction Framework.
Luke Hopkins • مدة القراءة: 4 دقائق
-
أخبار المنتجات
مع إصدار Android 17، سننتقل إلى معيار تطوير تكيفي أول. لم يعُد المستخدمون يعتمدون على شكل جهاز واحد، بل ينتقلون بين الهواتف والهواتف القابلة للطي والأجهزة اللوحية وأجهزة الكمبيوتر المحمولة وشاشات السيارات وبيئات الواقع الممتد الغامرة على مدار اليوم.
Fahd Imtiaz • مدة القراءة: 4 دقائق
البقاء على اطّلاع على آخر التحديثات
يمكنك تلقّي أحدث الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.