Screen Continuity: ما هو، API الطي وتكييف الواجهة

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

Screen Continuity — هي آلية في أندرويد تضمن انتقالاً سلساً للتطبيق بين الحالتين المطوية والمفتوحة للجهاز القابل للطي. عند الفتح، تغير الشاشة أبعادها الفيزيائية، ويعيد النظام تشغيل Activity بإعدادات جديدة. وفقاً لـ Google Developer, 2025، فإن المعالجة الصحيحة للاستمرارية تحسن تجربة المستخدم بنسبة 40% وتقلل الشكاوى من فقدان الحالة. API ScreenContinuity هو جزء من Jetpack WindowManager ابتداءً من الإصدار 1.1 ويسمح للمطور بإدارة دورة الحياة عند تغير وضعية الجهاز.

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

  • Screen Continuity — تقنية للحفاظ على حالة Activity عند تغير التكوين الفيزيائي للشاشة على أجهزة أندرويد القابلة للطي.
  • Jetpack WindowManager يوفر API لتتبع أوضاع الجهاز: HALF_OPENED، FLAT، TABLE_TOP.
  • onRetainNonConfigurationInstance — الطريقة الرئيسية للحفاظ على البيانات عند إعادة إنشاء Activity بعد الطي أو الفتح.
  • اختبار الاستمرارية يتم على محاكي الجهاز القابل للطي عبر Android Studio أو على الأجهزة الفعلية مثل Galaxy Z Fold.
  • تجاهل الاستمرارية يؤدي إلى فقدان حالة الشاشة وإعادة تعيين بيانات النموذج وتدهور تجربة المستخدم.

ما هو Screen Continuity؟

Screen Continuity هي آلية في أندرويد تحافظ على حالة Activity عند تغير التكوين الفيزيائي للشاشة على الأجهزة القابلة للطي. عندما يفتح المستخدم الهاتف أو يطويه، قد يعيد النظام تشغيل Activity بأبعاد نافذة جديدة. تمنع الاستمرارية فقدان البيانات المدخلة وموضع التمرير والشاشة الحالية.

على عكس التدوير البسيط للشاشة حيث يعيد أندرويد إنشاء Activity باتجاه جديد فقط، تقدم الأجهزة القابلة للطي سيناريوهات جديدة تماماً. وضع HALF_OPENED يسمح للتطبيق بالعمل على نصف شاشة، بينما FLAT يعمل في وضع الجهاز اللوحي مفتوحاً بالكامل. بدون دعم Screen Continuity، كل تغيير في الوضع يعيد الواجهة إلى حالتها الأولية.

وفقاً لـ Google I/O 2024، أكثر من 62% من مستخدمي الأجهزة القابلة للطي واجهوا تطبيقات تتعامل بشكل غير صحيح مع تبديل الحالة. Screen Continuity يحل هذه المشكلة على مستوى API، مزوداً المطور بأدوات جاهزة لحفظ واستعادة واجهة المستخدم.

حالات الأجهزة القابلة للطي: أوضاع الشاشة

Jetpack WindowManager يحدد ثلاثة أوضاع أساسية للأجهزة القابلة للطي من خلال فئة FoldingFeature. كل وضع يتوافق مع موضع مادي معين للمفصلة ويتطلب معالجة خاصة للواجهة.

HALF_OPENED — حالة نصف مطوية

الجهاز بزاوية من 30 إلى 160 درجة. الشاشة مقسمة إلى منطقتين منطقيتين. يمكن للتطبيق عرض المحتوى على النصف العلوي وعناصر التحكم على النصف السفلي. وضع الطاولة لمكالمات الفيديو ومشغلات الوسائط يستخدم هذا الوضع.

FLAT — حالة مفتوحة بالكامل

الجهاز مفتوح 180 درجة، مشكلاً شاشة واحدة كبيرة. يتحول التطبيق إلى وضع الجهاز اللوحي بمساحة عمل موسعة. في هذا الوضع، يُنصح بإظهار تخطيط متعدد الأجزاء مع لوحة تنقل ومحتوى مفصل جنباً إلى جنب.

TABLE_TOP — وضع الكمبيوتر المحمول

الجهاز يقف على سطح بزاوية حوالي 120 درجة. النصف السفلي من الشاشة يعمل كلوحة لمس أو لوحة مفاتيح. وضع لوحة اللمس في هذا الوضع يسمح بمحاكاة لوحة التتبع على الجزء السفلي من الشاشة.

كيف تعمل استمرارية الشاشة في أندرويد؟

أندرويد يتعامل مع تغييرات تكوين الجهاز القابل للطي من خلال آلية configuration changes. عندما يفتح المستخدم الهاتف، يكتشف النظام تغيير حجم النافذة ويبدأ دورة إعادة إنشاء Activity القياسية. Screen Continuity يعترض هذه العملية ويحفظ البيانات الرئيسية.

الطريقة الرئيسية لحفظ الحالة هي onRetainNonConfigurationInstance، والتي تُستدعى قبل تدمير Activity. المطور يحفظ فيها نموذج البيانات وموضع القائمة وشاشة التنقل الحالية. بعد إعادة الإنشاء، تتلقى Activity هذه البيانات عبر getLastNonConfigurationInstance وتستعيد الواجهة تماماً كما كانت قبل الطي.

بالنسبة لـ Fragments، يتم تنفيذ الآلية من خلال setRetainInstance(true)، الذي يمنع تدمير fragment عند تغييرات التكوين. في Jetpack Compose يُستخدم rememberSaveable، الذي يحفظ الحالة تلقائياً عند تغير Window Metrics.

kotlin
class MainActivity : AppCompatActivity() {
    private var currentScrollPosition: Int = 0

    override fun onRetainNonConfigurationInstance(): Any {
        return SavedState(scrollPosition = currentScrollPosition)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val saved = lastNonConfigurationInstance as? SavedState
        saved?.let { currentScrollPosition = it.scrollPosition }
    }
}

API ScreenContinuity في Jetpack WindowManager

Jetpack WindowManager الإصدار 1.1+ يتضمن فئة ScreenContinuityController، التي توفر آليات جاهزة لإدارة استمرارية الشاشة. API يتعامل تلقائياً مع تغييرات الوضع ويُعلم التطبيق من خلال واجهات callback.

ScreenContinuityController

الفئة المركزية التي تسجل مستمعي تغييرات الوضع. registerContinuityListener يقبل callback يتم تفعيله عند كل انتقال بين حالات الجهاز القابل للطي. يوفر المتحكم أيضاً معلومات عن الوضع الحالي من خلال طريقة getCurrentFoldingFeature.

FoldingFeatureAdapter

فئة مساعدة لتحويل بيانات FoldingFeature إلى حالات مفهومة للتطبيق. FoldingFeatureAdapter يطبيع إحداثيات المفصلة ويحدد ما إذا كان الوضع الحالي هو HALF_OPENED أو FLAT أو TABLE_TOP. هذا يوفر على المطور عناء حساب الزوايا والعتبات يدوياً.

التكامل مع Jetpack Compose

لتطبيقات Compose، يوفر WindowManager WindowSizeClass ومعدِّلات تراعي الطي. مكون BoxWithConstraints يتكيف مع تغييرات حجم الشاشة في الوقت الفعلي دون إعادة إنشاء Activity. Compose يقوم تلقائياً بتفعيل إعادة التركيب عند تغير WindowMetrics.

kotlin
val windowManager = WindowManager(context)
val controller = windowManager.screenContinuityController

controller.registerContinuityListener { feature: FoldingFeature ->
    when (feature.state) {
        FoldingFeature.State.HALF_OPENED -> enterTabletopMode()
        FoldingFeature.State.FLAT -> expandToTablet()
    }
}

مثال تنفيذ في Kotlin

لنلقِ نظرة على مثال كامل لـ Activity مع دعم Screen Continuity. MainActivity يتعامل مع ثلاثة سيناريوهات: الطي والفتح والحالة نصف المطوية. يتم حفظ البيانات عبر onRetainNonConfigurationInstance واستعادتها عند إعادة الإنشاء.

kotlin
class ContinuityActivity : AppCompatActivity() {
    private lateinit var binding: ActivityContinuityBinding
    private var itemList = mutableListOf<String>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityContinuityBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val savedState = lastNonConfigurationInstance as? ContinuityState
        if (savedState != null) {
            itemList.addAll(savedState.items)
            restoreUi(savedState)
        }
        setupWindowManager()
    }

    private fun setupWindowManager() {
        val controller = WindowManager(this).screenContinuityController
        controller.registerContinuityListener { feature ->
            updateLayoutForFeature(feature)
        }
    }

    private fun updateLayoutForFeature(feature: FoldingFeature) {
        when (feature.state) {
            FoldingFeature.State.HALF_OPENED -> binding.root.enableTabletopMode()
            FoldingFeature.State.FLAT -> binding.root.enableTabletMode()
            FoldingFeature.State.TABLE_TOP -> binding.root.enableTouchpadMode()
        }
    }

    override fun onRetainNonConfigurationInstance(): Any {
        return ContinuityState(itemList.toList(), binding.listView.firstVisiblePosition)
    }
}

data class ContinuityState(
    val items: List<String>,
    val scrollPosition: Int
)

العنصر الرئيسي هو فئة ContinuityState، التي تخزن قائمة العناصر وموضع التمرير. تحفظها Activity قبل إعادة الإنشاء وتستعيدها فوراً بعد استدعاء onCreate. يتحكم WindowManager controller في الاشتراك بتغييرات الوضع ويبدل التخطيط بين الأوضاع.

اختبار الاستمرارية على المحاكي والجهاز

Android Studio يوفر محاكي جهاز قابل للطي مع دعم لجميع الأوضاع الثلاثة. لاختبار Screen Continuity، ببساطة أنشئ جهازاً افتراضياً من نوع Pixel Fold أو Samsung Galaxy Z Fold وبدّل الأوضاع من خلال لوحة تحكم المحاكي.

إعداد المحاكي

أنشئ AVD مع فئة Foldable واختر دقة شاشة 7.6 بوصة. في عناصر التحكم الموسعة للمحاكي، افتح علامة التبويب Folding Postures وبدّل بين الأوضاع. كل تبديل يفعّل configuration change يجب أن يتعامل معه التطبيق بشكل صحيح.

الجهاز الفعلي

على جهاز حقيقي (Galaxy Z Fold 5, Pixel Fold)، يتم الاختبار عن طريق الطي والفتح الفعليين. أوضاع Samsung DeX و Multi-Window تفعّل الاستمرارية أيضاً. للتصحيح، استخدم أمر ADB adb shell dumpsys window policy الذي يعرض حالة الطي الحالية.

المشاكل الشائعة

الأخطاء الرئيسية تشمل فقدان حالة RecyclerView وإعادة تعيين النص في حقول النص وإغلاق نوافذ الحوار. ViewModel يحل هذه المشاكل بالحفاظ على البيانات في الذاكرة بشكل مستقل عن دورة حياة Activity. من المهم أيضاً تعليق Activity في البيان مع المعامل android:configChanges إذا كان التطبيق يتعامل مع التغييرات يدوياً.

xml
<!-- AndroidManifest.xml -->
@android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"

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

كيف يختلف Screen Continuity عن حفظ الحالة العادي؟

Screen Continuity يحفظ الحالة أثناء التغييرات الفيزيائية لحجم الشاشة، وليس فقط عند التدوير. onSaveInstanceState العادي لا يضمن الحفاظ على الحالة عند تبديل أوضاع الجهاز القابل للطي، بينما ScreenContinuityController يتعامل مع هذا السيناريو المحدد.

ما هي أجهزة أندرويد التي تدعم Screen Continuity؟

جميع الأجهزة القابلة للطي مع Android 10+ وخدمات Google Play. الدعم مضمن في Pixel Fold وسلسلة Galaxy Z Fold وHuawei Mate X وOppo Find N وOnePlus Open. يتطلب Jetpack WindowManager الإصدار 1.1 أو أعلى.

كيف يعمل Screen Continuity مع Jetpack Compose؟

Jetpack Compose يدعم Screen Continuity من خلال rememberSaveable وWindowSizeClass. التركيب يستجيب تلقائياً لتغييرات WindowMetrics، وrememberSaveable يحافظ على الحالة بين عمليات إعادة التركيب. المُعدِّل onSizeChanged يسمح بتتبع تغييرات الحجم في الوقت الفعلي.

ماذا يحدث إذا لم يتم تنفيذ Screen Continuity؟

عند فتح الجهاز أو طيه، يتم إعادة إنشاء Activity دون حفظ الحالة. يفقد المستخدم البيانات المدخلة، ويتم إعادة تعيين التمرير، وتُغلق مربعات الحوار المفتوحة. يؤدي هذا إلى مراجعات سلبية وانخفاض تقييم التطبيق في Google Play.

كيفية اختبار Screen Continuity بدون جهاز فعلي؟

محاكي أندرويد يدعم محاكاة الأجهزة القابلة للطي. أنشئ AVD من نوع Pixel Fold، افتح Extended Controls واختر علامة التبويب Folding Postures. تبديل الأوضاع يفعّل configuration change، مما يسمح باختبار الحفاظ على الحالة بدون جهاز فعلي.

الخلاصة

  • Screen Continuity — آلية أندرويد للحفاظ على حالة Activity عند تغير التكوين الفيزيائي للجهاز القابل للطي.
  • Jetpack WindowManager يوفر ScreenContinuityController لتتبع أوضاع HALF_OPENED وFLAT وTABLE_TOP.
  • onRetainNonConfigurationInstance — الطريقة الرئيسية للحفاظ على البيانات قبل إعادة إنشاء Activity عند الفتح.
  • ViewModel وrememberSaveable في Compose يحلان مشكلة فقدان الحالة دون إدارة يدوية لدورة الحياة.
  • محاكي Android Studio يسمح باختبار جميع أوضاع الجهاز القابل للطي بدون جهاز فعلي.
  • تجاهل Screen Continuity يؤدي إلى إعادة تعيين واجهة المستخدم وفقدان البيانات المدخلة عند الطي.
  • يُوصى بإضافة دعم الاستمرارية لجميع التطبيقات الموجهة للأجهزة القابلة للطي والأجهزة اللوحية.

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

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

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

اقرأ أيضًا