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

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

باستخدام التعبيرات الديناميكية، لن تحتاج إلى إعادة تحميل اللوحة بأكملها عند تغيير محتواها. لإنشاء تجربة أكثر جاذبية في المربّعات، يمكنك تحريك هذه العناصر الديناميكية.

ربط التعبيرات الديناميكية بمصادر البيانات

يحتوي كل من مساحتَي الاسم androidx.wear.protolayout وandroidx.wear.protolayout.material على العديد من الفئات التي تقبل حقولها تعبيرات ديناميكية. وتشمل بعض الأمثلة ما يلي:

لاستخدام تعبير ديناميكي كقيمة محتملة لعنصر في المربّع، استخدِم نوع السمة الديناميكية *Prop المناسب للعنصر وأدخِل مصدر البيانات إلى طريقة setDynamicValue() في فئة أداة إنشاء نوع السمة الديناميكية.

تتيح المربّعات استخدام أنواع السمات الديناميكية التالية:

عند استخدام تعبير ديناميكي يؤثر في الأبعاد المادية، أي قيمة في مربّع باستثناء اللون، عليك أيضًا تحديد مجموعة من القيود ذات الصلة، مثل تنسيق السلسلة. تسمح هذه القيود لبرنامج العرض في النظام بتحديد الحد الأقصى للمساحة التي يمكن أن تشغلها قيمة داخل المربّع. عادةً، يتم تحديد هذه القيود على مستوى العنصر، وليس على مستوى التعبير الديناميكي، وذلك من خلال استدعاء طريقة تبدأ بـ setLayoutConstraintsForDynamic*.

يوضّح مقتطف الرمز التالي كيفية عرض التعديلات على معدّل نبضات القلب باستخدام 3 أرقام، مع قيمة احتياطية تبلغ --:

override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(
                Timeline.fromLayoutElement(
                    Text.Builder(
                        this,
                        TypeBuilders.StringProp.Builder("--")
                            .setDynamicValue(
                                PlatformHealthSources.heartRateBpm()
                                    .format()
                                    .concat(DynamicBuilders.DynamicString.constant(" bpm"))
                            )
                            .build(),
                        TypeBuilders.StringLayoutConstraint.Builder("000").build(),
                    )
                        .build()
                )
            )
            .build()
    )

استخدام عدد صغير من التعبيرات ضمن مربّع واحد

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

دمج البيانات الديناميكية في عنصر حالة

يمكنك دمج آخر مجموعة من التعديلات من مصادر البيانات في حالة، والتي يمكنك تمريرها إلى المربّع لعرض القيمة.

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

  1. أنشئ مجموعة من المفاتيح التي تمثّل القيم المختلفة لحالة المربّع. ينشئ هذا المثال مفاتيحًا لتسجيل كمية المياه التي تم تناولها وملاحظة qqq:

    companion object {
        val KEY_WATER_INTAKE = intAppDataKey("key_water_intake")
        val KEY_NOTE = stringAppDataKey("key_note")
    }

  2. في عملية تنفيذ onTileRequest()، استدعِ الدالة setState() وأنشئ عمليات ربط أولية من كل مفتاح بقيمة بيانات ديناميكية معيّنة:

    override fun onTileRequest(
        requestParams: RequestBuilders.TileRequest
    ): ListenableFuture<Tile?> {
        // If the tile hasn't had any state set yet, use the default values
        val state =
            if (requestParams.currentState.keyToValueMapping.isNotEmpty())
                requestParams.currentState
            else
                StateBuilders.State.Builder()
                    .setStateMap(
                        dynamicDataMapOf(
                            KEY_WATER_INTAKE mapTo 200,
                            KEY_NOTE mapTo "Good"
                        )
                    )
                    .build()
    
        return Futures.immediateFuture(
            Tile.Builder()
                // Set resources, timeline, and other tile properties.
                .setState(state)
                .build()
        )
    }

  3. عند إنشاء تخطيطك، في المكان الذي تريد عرض هذه البيانات فيه من حالة، استخدِم عنصرًا من النوع Dynamic*. يمكنك أيضًا استدعاء animate() لعرض رسم متحرك من القيمة السابقة إلى القيمة الحالية:

    val waterIntakeValue =
        DynamicBuilders.DynamicInt32.from(KEY_WATER_INTAKE)

  4. يمكنك أيضًا تعديل الحالة بقيم جديدة عند الحاجة. يمكن أن يكون هذا الجزء من LoadAction البلاطة.

    في هذا المثال، تم تعديل قيمة كمية المياه المتناوَلة إلى 400:

    val loadAction =
        loadAction(
            dynamicDataMapOf(
                KEY_WATER_INTAKE mapTo 400,
                KEY_NOTE mapTo "Outstanding"
            )
        )