عرض التحديثات الدورية في المربّعات

يمكنك إنشاء مربّعات تتضمّن محتوًى يتغيّر بمرور الوقت.

استخدام المخططات الزمنية

يتألّف المخطّط الزمني من مثيل واحد أو أكثر من TimelineEntry، ويحتوي كلّ منها على تنسيق يتم عرضه خلال فترة زمنية محدّدة. تحتاج جميع المربّعات إلى مخطّط زمني.

المخطط الزمني للمربّعات الذي يتضمّن إدخالَين في المخطط الزمني، كلّ منهما يتضمّن تخطيطًا
مخطط زمني للمربّع

المربّعات التي تتضمّن إدخالاً واحدًا

يمكن غالبًا وصف المربّع باستخدام TimelineEntry واحد. يكون التنسيق ثابتًا، ولا تتغيّر سوى المعلومات الموجودة داخله. على سبيل المثال، يعرض مربّع تقدّم لياقتك البدنية خلال اليوم دائمًا التنسيق نفسه، على الرغم من أنّه يمكنك تعديل هذا التنسيق لعرض قيم مختلفة. في هذه الحالات، لا يمكنك معرفة متى قد يتغيّر المحتوى مسبقًا.

في ما يلي مثال على مربّع يتضمّن TimelineEntry واحدًا:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            // We add a single timeline entry when our layout is fixed, and
            // we don't know in advance when its contents might change.
            .setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))
            .build()
    return Futures.immediateFuture(tile)
}

إدخالات المخطط الزمني المحدّدة بفترة زمنية

يمكن أن يحدّد TimelineEntry بشكل اختياري فترة صلاحية، ما يسمح للمربّع بتغيير تنسيقه في وقت معروف بدون أن يطلب التطبيق عرض مربّع جديد.

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

تسمح واجهة برمجة التطبيقات للمربّعات بفترات صلاحية متداخلة، حيث يتم عرض الشاشة التي تحتوي على أقصر فترة زمنية متبقية. لا يتم عرض سوى حدث واحد في كل مرة.

يمكن للمطوّرين تقديم إدخال احتياطي تلقائي. على سبيل المثال، يمكن أن يحتوي مربّع جدول الأعمال على مربّع بفترة صلاحية غير محدودة، ويتم استخدامه إذا لم يكن أي إدخال آخر في المخطط الزمني صالحًا، كما هو موضّح في عينة التعليمات البرمجية التالية:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
    val timeline = Timeline.Builder()

    // Add fallback "no meetings" entry
    // Use the version of TimelineEntry that's in androidx.wear.protolayout.
    timeline.addTimelineEntry(
        TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()
    )

    // Retrieve a list of scheduled meetings
    val meetings = MeetingsRepo.getMeetings()
    // Add a timeline entry for each meeting
    meetings.forEach { meeting ->
        timeline.addTimelineEntry(
            TimelineBuilders.TimelineEntry.Builder()
                .setLayout(getMeetingLayout(meeting))
                .setValidity(
                    // The tile should disappear when the meeting begins
                    // Use the version of TimeInterval that's in
                    // androidx.wear.protolayout.
                    TimelineBuilders.TimeInterval.Builder()
                        .setEndMillis(meeting.dateTimeMillis)
                        .build()
                )
                .build()
        )
    }

    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setTileTimeline(timeline.build())
            .build()
    return Futures.immediateFuture(tile)
}

إعادة تحميل مربّع

قد تنتهي صلاحية المعلومات المعروضة على المربّع بعد فترة من الوقت. على سبيل المثال، لا يكون مربّع الطقس الذي يعرض درجة الحرارة نفسها طوال اليوم دقيقًا.

للتعامل مع البيانات التي تنتهي صلاحيتها، اضبط فترة صلاحية عند إنشاء مربّع، تحدّد المدة التي يكون فيها المربّع صالحًا. في مثال مربّع الطقس، يمكنك تعديل محتواه كل ساعة، كما هو موضّح في نموذج الرمز البرمجي التالي:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))
            .build()
    )

عند ضبط فترة صلاحية، يستدعي النظام onTileRequest() بعد انتهاء الفترة بفترة قصيرة. إذا لم تضبط فترة صلاحية، لا يستدعي النظام onTileRequest().

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

fun eventDeletedCallback() {
     TileService.getUpdater(context)
             .requestUpdate(MyTileService::class.java)
}

اختيار سير عمل التعديل

استخدِم أفضل الممارسات التالية لتحديد كيفية ضبط تعديلات المربّع:

  • إذا كان التعديل متوقّعًا، مثلاً إذا كان للحدث التالي في تقويم المستخدم، استخدِم مخطّطًا زمنيًا.
  • عند جلب بيانات المنصة، استخدِم ربط البيانات حتى يعدّل النظام البيانات تلقائيًا.
  • إذا كان من الممكن حساب التعديل على الجهاز فقط في فترة زمنية قصيرة، مثل تعديل موضع صورة على مربّع شروق الشمس، استخدِم onTileRequest().

    يكون هذا مفيدًا بشكل خاص عندما تحتاج إلى إنشاء جميع الصور مسبقًا. إذا كنت بحاجة إلى إنشاء صورة جديدة في وقت لاحق، استخدِم setFreshnessIntervalMillis().

  • إذا كنت تجري عملاً مكثفًا في الخلفية بشكل متكرّر، مثل إجراء طلبات بيانات الطقس، استخدِم WorkManager، واعرض التعديلات على المربّع.

  • إذا كان التعديل استجابةً لحدث خارجي، مثل تشغيل الأضواء أو تلقّي رسالة إلكترونية أو تعديل ملاحظة، أرسِل رسالة من ميزة المراسلة عبر السحابة الإلكترونية من Firebase (FCM) لجعل تطبيقك نشطًا مرة أخرى، ثم اعرض التعديلات على المربّع.

  • إذا كانت عملية مزامنة بيانات المربّع قد تكون مكلفة، اتّبِع الخطوات التالية:

    1. جدوِلة مزامنة البيانات
    2. بدء مؤقت لمدة ثانية أو ثانيتين
    3. إذا تلقّيت تعديلاً من مصدر بيانات بعيد قبل انتهاء الوقت، اعرض القيمة المعدَّلة من مزامنة البيانات. وبخلاف ذلك، اعرض قيمة محلية مخزّنة مؤقتًا.