تنسيق واجهة المستخدم مع شريط حالة النظام

حتى الإصدار Wear OS 7 (واجهة برمجة التطبيقات 37)، لم تكن المنصة تعرض شريط حالة النظام فوق نوافذ التطبيقات، بل كانت التطبيقات تستحوذ على الشاشة بأكملها ويمكنها عرض أي محتوى في الجزء العلوي (عند الساعة 12) (مثل ساعة TimeText داخل التطبيق أو العناوين المنحنية المخصّصة أو عناصر التحكّم في الجزء العلوي).

بدءًا من Wear OS 8، والذي يتوفّر الآن للاختبار في النسخة الحصرية المبكرة من محاكي الإصدار التجريبي من Wear OS 7.1 (الإصدار 37.2-beta1 من واجهة برمجة التطبيقات)، يعرض النظام شريط الحالة فوق نوافذ التطبيقات عند موضع الساعة 12 لعرض الوقت ومؤشرات الحالة. لتجنُّب التداخل مع شريط الحالة في النظام، يجب أن تتوقف التطبيقات عن عرض ساعتها الخاصة (TimeText) وأن تلتزم بالهوامش الداخلية لنافذة شريط الحالة العلوي (يتم التعامل مع ذلك تلقائيًا من خلال AppScaffold وScreenScaffold من الإصدار 1.8 من Wear Compose فصاعدًا)، أو إخفاء شريط الحالة في النظام عند الحاجة إلى تجربة غامرة بملء الشاشة.

شريط حالة النظام في Wear OS 8
الشكل 1. شريط حالة النظام في Wear OS 8

وتشمل المزايا الرئيسية ما يلي:

  • الاتساق المرئي: أسلوب خط موحّد للساعة وموضعها ولوحة خلفية موحّدة على مستوى النظام وجميع التطبيقات
  • مؤشرات حالة النظام: يسمح هذا الإذن للمنصة بعرض رموز الحالة (مثل مؤشرات الميكروفون والموقع الجغرافي النشطَين أو حالة إمكانية الاتصال أو معلومات البطارية) والوقت على جميع مساحات العرض. يظهر رمز واحد فقط في كل مرة، بناءً على الأولوية.
  • التمرير التلقائي وتنسيق الانتقال: عند إقران Jetpack Compose مع Wear OS 1.8، يتم إخفاء شريط حالة النظام تلقائيًا عندما يتصفّح المستخدمون المحتوى ويظهر مرة أخرى بعد فترة قصيرة (ثانيتين) من عدم النشاط.

إعداد تطبيقك

للبدء، أكمِل الخطوات الأساسية التالية:

  1. ثبِّت الإصدار الأولي من "استوديو Android" (Canary).
  2. في SDK Manager، نزِّل صورة نظام المحاكي للنسخة الحصرية من Wear OS 7.1 (المستوى 37.2-beta1 من واجهة برمجة التطبيقات). يتيح هذا الإصدار استخدام شريط الحالة في نظام Wear OS 8 قبل إطلاقه، وذلك قبل توفّر حزمة تطوير البرامج (SDK) لنظام Wear OS 8.
  3. في "أداة إدارة الأجهزة"، أنشِئ جهازًا افتراضيًا يعمل بنظام التشغيل Wear OS وشغِّله باستخدام نسخة واجهة برمجة التطبيقات 37.2-beta1.

لإتاحة شريط حالة النظام في تطبيقك، يُرجى تحديث إصدار targetSdk في تطبيقك إلى الإصدار 35 أو إصدار أحدث. لا يفعّل النظام الأساسي شريط حالة النظام إلا للتطبيقات التي تستهدف المستوى 35 من واجهة برمجة التطبيقات أو المستويات الأحدث للحفاظ على التوافق مع الأنظمة القديمة للتطبيقات القديمة. بالإضافة إلى ذلك، يجب تحديث تبعيّات Wear Compose إلى أحدث إصدار أولي، وهو حاليًا 1.8.0-alpha03، كما هو موضّح في مقتطف الرمز التالي. إذا كان تطبيقك يستخدم إصدارًا قديمًا من Wear Compose، يمكنك استخدام مهارة نقل البيانات إلى Wear Compose Material 3 لتسهيل عملية النقل.

android {
    defaultConfig {
        targetSdk = 35
    }
}

dependencies {
    implementation("androidx.wear.compose:compose-foundation:1.8.0-alpha03")
    implementation("androidx.wear.compose:compose-material3:1.8.0-alpha03")
}

استخدام شريط حالة النظام

في أحدث إصدار أولي من Wear Compose Material 3 1.8.0، وهو حاليًا ‎1.8.0-alpha03، تفعّل المكتبة تطبيقك تلقائيًا من خلال دمج السمة com.google.wear.ENABLE_GLOBAL_STATUS_BAR <meta-data> في AndroidManifest.xml. أثناء التشغيل، يتحقّق AppScaffold وScreenScaffold مما إذا كان شريط حالة النظام مفعَّلاً على الجهاز وما إذا تم ضبط سمة الموافقة في ملف البيان على true:

  • في محاكي النسخة الحصرية / Wear OS 8 والإصدارات الأحدث (عند الموافقة): يمنع AppScaffold TimeText الداخلي الخاص به لكي يظهر شريط حالة النظام بشكل واضح في موضع الساعة 12 بدون تكرار. ScreenScaffold يعيد حساب contentPadding ليأخذ في الاعتبار حدود شريط الحالة ويُنسّق إخفاء شريط الحالة وإظهاره أثناء التمرير في القائمة.
  • على الأجهزة التي تعمل بنظام التشغيل Wear OS 7 والإصدارات الأقدم (أو في حال عدم تفعيل الميزة): AppScaffold يتم تلقائيًا الرجوع إلى عرض TimeText العادي داخل التطبيق، مع الحفاظ على التوافق الكامل مع الأنظمة القديمة من قاعدة رموز برمجية واحدة.
@Composable
fun GsbSampleApp() {
    // AppScaffold coordinates the system status bar across the app
    // and falls back to rendering TimeText on Wear OS 7 and earlier.
    AppScaffold {
        val columnState = rememberTransformingLazyColumnState()

        // ScreenScaffold includes status bar top inset clearance in
        // contentPadding and hides/shows the status bar during list scrolling.
        ScreenScaffold(scrollState = columnState) { contentPadding ->
            TransformingLazyColumn(
                state = columnState,
                contentPadding = contentPadding,
            ) {
                item {
                    ListHeader { Text("Hello Status Bar") }
                }
                items(count = 15) { index ->
                    Button(onClick = { /* Handle click */ }) {
                        Text("Item #${index + 1}")
                    }
                }
            }
        }
    }
}

إليك ما يمكن توقُّعه عند تشغيل النموذج:

  • في وضع السكون (أعلى القائمة): يظهر شريط حالة النظام في موضع الساعة 12. يظهر عنوان "Hello Status Bar" أسفل منطقة شريط الحالة بدون اقتصاص أو تداخل.
  • التمرير للأسفل: أثناء التمرير خلال عناصر القائمة، يختفي شريط الحالة، ويتم تمرير عناصر القائمة من الحافة إلى الحافة خلف الإطار العلوي.
  • الخمول: عند التوقف عن التمرير ورفع إصبعك عن الشاشة، يظهر شريط الحالة تلقائيًا بعد ثانيتين تقريبًا.

التعامل مع السيناريوهات الشائعة والتخصيصات

توضّح الأقسام التالية كيفية التعامل مع السيناريوهات الشائعة التي قد تواجهها عند العمل مع شريط حالة النظام.

التعامل مع الشاشات غير القابلة للتمرير (الثابتة)

على الشاشات التي تستخدم تنسيقًا ثابتًا (مثل Column أو Box) بدلاً من قائمة قابلة للتمرير، يمكنك تطبيق contentPadding الذي يوفّره ScreenScaffold على التنسيق الجذر حتى لا تتداخل عناصر في واجهة المستخدم في أعلى الشاشة مع شريط حالة النظام:

AppScaffold {
    ScreenScaffold { contentPadding ->
        Column(modifier = Modifier.padding(contentPadding)) {
            Text("Static Screen Content")
        }
    }
}

العمل مع المكونات التفاعلية بملء الشاشة

تخفي المكوّنات التفاعلية بملء الشاشة في Wear Compose Material 3، بما في ذلك AlertDialog وDialog وStepper وTimePicker وDatePicker، شريط حالة النظام تلقائيًا أثناء ظهورها على الشاشة، ما يتيح لعناصر التحكّم الوصول الكامل إلى الجزء العلوي من الشاشة الدائرية. عند إغلاق الإشعار، تتم استعادة شريط حالة النظام تلقائيًا باستخدام واجهة برمجة التطبيقات الخاصة بوحدة التحكّم في هوامش النوافذ.

التبديل إلى الوضع المجسم

للتبديل إلى وضع مجسم، حيث يتم إخفاء كل من شريط حالة النظام وTimeText المحلي، يمكنك تطبيق المُعدِّل Modifier.suppressStatusBar على تطبيقك أو شاشتك أو المكوّن. يجب تخصيص الوضع المجسم للشاشات التي تظهر للمستخدم لفترة وجيزة (مثل تراكبات التأكيد ومربّعات الحوار) أو التي تستخدم الشاشة بأكملها (مثل مؤشرات التقدم بملء الشاشة).

حالات استخدام "الوضع المجسم" على مستوى الشاشة

إذا كانت هناك شاشة معيّنة فقط في تطبيقك يجب أن تكون بملء الشاشة أو غامرة، يمكنك تطبيق Modifier.suppressStatusBar على ScreenScaffold. عندما تكون هذه الشاشة نشطة، يخفي "ScreenScaffold" تلقائيًا شريط حالة النظام ويصغّر حشو شريط الحالة العلوي إلى 0.dp. عند الرجوع إلى شاشات أخرى، يستعيد تطبيق "ScreenScaffold" شريط حالة النظام:

AppScaffold {
    ScreenScaffold(modifier = Modifier.suppressStatusBar()) { contentPadding ->
        Box(modifier = Modifier.fillMaxSize().padding(contentPadding)) {
            // Full-screen immersive content
        }
    }
}

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

حالات استخدام "الوضع المجسم" على مستوى التطبيق

إذا كان تطبيقك بالكامل يقدّم تجربة غامرة بملء الشاشة، يمكنك تطبيق Modifier.suppressStatusBar على AppScaffold لإخفاء شريط حالة النظام على جميع الشاشات:

// Apply Modifier.suppressStatusBar() to AppScaffold to suppress the status bar
// and collapse insets across all child screens.
AppScaffold(modifier = Modifier.suppressStatusBar()) {
    SwipeDismissableNavHost(
        navController = navController,
        startDestination = "home",
    ) {
        // Nested screens inherit suppression and 0.dp padding
    }
}

عرض عمليات إلغاء نص الوقت المخصّص

إذا كنت بحاجة إلى عرض عنوان منحني مخصّص أو إيقاف شريط حالة النظام مؤقتًا على شاشة معيّنة أو في تطبيقك بالكامل أثناء عملية نقل البيانات إلى Wear OS 8، يمكنك تمرير دالة مركّبة مخصّصة من النوع timeText لإخفاء شريط حالة النظام:

// Screen-level custom TimeText override:
ScreenScaffold(
    timeText = { TimeText { timeTextCurvedText("Custom Status") } },
) {
    // Content
}

// App-level opt-out using in-app TimeText:
AppScaffold(
    timeText = { TimeText() },
) {
    // Screens
}

التنفيذ باستخدام Views (لا يُنصح به)

إذا كان تطبيقك يستخدم Android Views بدلاً من Jetpack Compose لنظام التشغيل Wear OS، يمكنك الموافقة باستخدام AndroidManifest.xml. على عكس أحدث إصدار أولي من Wear Compose Material 3، الذي يفعّل شريط الحالة في النظام تلقائيًا، يجب أن تفعّل التطبيقات المستندة إلى العرض هذه الميزة صراحةً من خلال إضافة العلامة ENABLE_GLOBAL_STATUS_BAR <meta-data> داخل <application>:

<application ...>
    <meta-data
        android:name="com.google.wear.ENABLE_GLOBAL_STATUS_BAR"
        android:value="true" />
</application>

مراقبة الأجزاء الداخلية في أعلى النافذة

استخدِم ViewCompat.setOnApplyWindowInsetsListener وتحقَّق من قيمة windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()). عندما يكون statusBarInsets.top > 0، أزِل واجهة المستخدم القديمة التي تظهر في أعلى الشاشة واضبط الحشو العلوي، وإلا يمكنك الرجوع إلى واجهة المستخدم القديمة:

ViewCompat.setOnApplyWindowInsetsListener(rootView) { view, windowInsets ->
    val statusBarInsets = windowInsets.getInsets(
        WindowInsetsCompat.Type.statusBars()
    )

    if (statusBarInsets.top > 0) {
        // status bar is visible: remove legacy 12 o'clock UI and apply top inset padding
        view.updatePadding(top = statusBarInsets.top)
    } else {
        // status bar is not visible: fall back to legacy UI and padding
    }

    WindowInsetsCompat.CONSUMED
}

إخفاء شريط الحالة وإظهاره آليًا

على عكس ScreenScaffold في Compose، يجب أن تخفي التطبيقات المستندة إلى العرض أو تعرض شريط حالة النظام بشكل صريح (على سبيل المثال، عند الدخول إلى وضع ملء الشاشة أو تنسيق سلوك التمرير بعيدًا) باستخدام WindowInsetsControllerCompat:

val insetsController = WindowCompat.getInsetsController(window, window.decorView)

// Hide the status bar
insetsController.hide(WindowInsetsCompat.Type.statusBars())

// Show the status bar
insetsController.show(WindowInsetsCompat.Type.statusBars())

اختبار تطبيقك

عند اختبار تطبيقك على محاكي الإصدار التجريبي الحصري من Wear OS 7.1 (الإصدار 37.2-beta1 من واجهة برمجة التطبيقات)، يُرجى التحقّق مما يلي:

  • ظهور الساعة مرة واحدة فقط: تأكَّد من ظهور وقت شريط حالة النظام فقط في موضع الساعة 12 وعدم تداخله مع TimeText القديم داخل التطبيق ومحتوى التطبيق.
  • المساحة المتروكة في الأعلى: تأكَّد من ظهور عناوين الشاشة والعناوين الرئيسية والأزرار العلوية أسفل شريط الحالة.
  • التراكبات ومربّعات الحوار بملء الشاشة: تأكَّد من أنّ مربّعات الحوار وأدوات الاختيار وأدوات التقدّم والأنشطة المخصّصة بملء الشاشة تخفي شريط الحالة عند فتحها، وأنّها تستعيده عند إغلاقها.