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

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

بدءًا من Wear OS 8، وهو متاح الآن للاختبار في النسخة المبكرة الحصرية من محاكي Wear OS 7.1 Beta Preview (الإصدار 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 Preview (الإصدار التجريبي 1 من واجهة برمجة التطبيقات 37.2). يتيح هذا الإصدار استخدام شريط الحالة في نظام Wear OS 8 قبل إطلاقه، وذلك قبل توفّر حزمة تطوير البرامج (SDK) لنظام Wear OS 8.
  3. في "أداة إدارة الأجهزة"، أنشِئ جهازًا افتراضيًا يعمل بنظام التشغيل Wear OS وشغِّله باستخدام نسخة واجهة برمجة التطبيقات 37.2-beta1.

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

android {
    defaultConfig {
        targetSdk = 35
    }
}

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

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

في أحدث إصدار أولي من Wear Compose Material 3 1.8.0 (حاليًا 1.8.0-alpha02)، تفعّل المكتبة تطبيقك تلقائيًا من خلال دمج السمة 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 المحلي، أضِف الدالة المركّبة StatusBarSuppression إلى تطبيقك أو شاشتك. يجب تخصيص الوضع المجسم للشاشات التي يراها المستخدم لفترة وجيزة (مثل تراكبات التأكيد ومربعات الحوار) أو التي تستخدم الشاشة بأكملها (مثل مؤشرات التقدم بملء الشاشة).

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

إذا كانت شاشة معيّنة فقط في تطبيقك يجب أن تكون بملء الشاشة أو غامرة، يمكنك استدعاء StatusBarSuppression() ضمن محتوى ScreenScaffold. يخفي ScreenScaffold شريط حالة النظام تلقائيًا (ويحذف المساحة المتروكة في أعلى شريط الحالة) عندما تكون تلك الشاشة نشطة، ثم يستعيد شريط حالة النظام عند الرجوع إلى الشاشات الأخرى:

AppScaffold {
    ScreenScaffold() {
        StatusBarSuppression()
        // Full-screen immersive content
    }
}

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

إذا كان تطبيقك بالكامل (أو Activity) يقدّم تجربة غامرة بملء الشاشة على جميع الشاشات، استخدِم StatusBarSuppression على مستوى AppScaffold وأدرِج المحتوى لإخفاء شريط الحالة في النظام على جميع الشاشات:

// Use StatusBarSuppression at AppScaffold level and wrap your content
// to suppress status bar in the entire scaffold.
AppScaffold {
    StatusBarSuppression {
        SwipeDismissableNavHost(...) {
            // 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 قديم داخل التطبيق ومحتوى التطبيق.
  • المساحة المتروكة في الأعلى: تأكَّد من ظهور عناوين الشاشة والعناوين الرئيسية والأزرار العلوية أسفل شريط الحالة.
  • التراكبات ومربّعات الحوار بملء الشاشة: تأكَّد من أنّ مربّعات الحوار وأدوات الاختيار وأدوات التقدّم والأنشطة المخصّصة بملء الشاشة تخفي شريط الحالة عند فتحها، وأنّها تستعيده عند إغلاقها.