แสดงการอัปเดตแบบไดนามิกในการ์ด

ตั้งแต่ Tiles 1.2 เป็นต้นไป คุณสามารถสตรีมการอัปเดตข้อมูลแพลตฟอร์มได้โดยใช้นิพจน์แบบไดนามิก จากนั้นจึงเชื่อมโยงการอัปเดตเหล่านี้กับภาพเคลื่อนไหวในการ์ด แอปจะได้รับการอัปเดตค่านี้ทุกวินาที

เมื่อใช้นิพจน์แบบไดนามิก คุณไม่จำเป็นต้องรีเฟรชทั้งการ์ดเมื่อมีการเปลี่ยนแปลงเนื้อหา หากต้องการให้การ์ดมีการใช้งานที่น่าสนใจยิ่งขึ้น ให้ใส่ภาพเคลื่อนไหวให้กับวัตถุแบบไดนามิกเหล่านั้น

เชื่อมโยงนิพจน์แบบไดนามิกกับแหล่งข้อมูล

เนมสเปซ androidx.wear.protolayout และ androidx.wear.protolayout.material มีคลาสหลายคลาสที่ช่องยอมรับนิพจน์แบบไดนามิก ตัวอย่างบางส่วนมีดังนี้

หากต้องการใช้นิพจน์แบบไดนามิกเป็นค่าที่เป็นไปได้สําหรับองค์ประกอบในการ์ด ให้ใช้*Propประเภทพร็อพเพอร์ตี้แบบไดนามิกที่สอดคล้องกันขององค์ประกอบ แล้วส่งแหล่งข้อมูลไปยังsetDynamicValue()เมธอดของคลาสบิลเดอร์ของประเภทพร็อพเพอร์ตี้แบบไดนามิก

ไทล์รองรับประเภทพร็อพเพอร์ตี้แบบไดนามิกต่อไปนี้

  • สำหรับมิติข้อมูลเชิงเส้นที่วัดเป็นพิกเซลที่ไม่ขึ้นอยู่กับการแสดงผล ให้ใช้ DimensionBuilders.DpProp
  • สำหรับมิติข้อมูลเชิงมุมที่วัดเป็นองศา ให้ใช้ DimensionBuilders.DegreesProp
  • สำหรับค่าสตริง ให้ใช้ TypeBuilders.StringProp
  • สำหรับค่าสี ให้ใช้ ColorBuilders.ColorProp
  • สำหรับค่าทศนิยม ให้ใช้ TypeBuilders.FloatProp

เมื่อคุณใช้นิพจน์แบบไดนามิกที่ส่งผลต่อมิติข้อมูลจริง (ค่าใดก็ตามในการ์ด ยกเว้นสี) คุณต้องระบุชุดข้อจำกัดที่เกี่ยวข้องด้วย เช่น รูปแบบสตริง ข้อจำกัดเหล่านี้ช่วยให้โปรแกรมแสดงผลของระบบระบุพื้นที่สูงสุดที่ค่าหนึ่งๆ สามารถใช้ภายในการ์ดได้ โดยปกติแล้ว คุณจะต้องระบุข้อจำกัดเหล่านี้ที่ระดับองค์ประกอบ ไม่ใช่ที่ระดับนิพจน์แบบไดนามิก โดยการเรียกใช้เมธอดที่ขึ้นต้นด้วย 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. สร้างชุดคีย์ที่แสดงค่าต่างๆ ของสถานะของการ์ด ตัวอย่างนี้จะสร้างคีย์สำหรับการดื่มน้ำและโน้ต

    Kotlin

    companion object {
        val KEY_WATER_INTAKE = AppDataKey<DynamicInt32>("water_intake")
        val KEY_NOTE = AppDataKey<DynamicString>("note")
    }

    Java

    private static final AppDataKey<DynamicInt32> KEY_WATER_INTAKE =
        new AppDataKey<DynamicInt32>("water_intake");
    private static final AppDataKey<DynamicString> KEY_NOTE =
        new AppDataKey<DynamicString>("note");
  2. ในการใช้งาน onTileRequest() ให้เรียกใช้ setState() และสร้างการแมปเริ่มต้นจากแต่ละคีย์ไปยังค่าข้อมูลแบบไดนามิกที่เฉพาะเจาะจง ดังนี้

    Kotlin

    override fun onTileRequest(requestParams: TileRequest):
            ListenableFuture<Tile> {
        val state = State.Builder()
            .addKeyToValueMapping(KEY_WATER_INTAKE,
                DynamicDataBuilders.DynamicDataValue.fromInt(200))
            .addKeyToValueMapping(KEY_NOTE,
                DynamicDataBuilders.DynamicDataValue.fromString("Note about day"))
        .build()
        // ...
    
        return Futures.immediateFuture(Tile.Builder()
            // Set resources, timeline, and other tile properties.
            .setState(state)
            .build()
        )

    Java

    @Override
    protected ListenableFuture<Tile> onTileRequest(
                ListenableFuture<Tile> {
        State state = new State.Builder()
            .addKeyToValueMapping(KEY_WATER_INTAKE,
                DynamicDataBuilders.DynamicDataValue.fromInt(200))
            .addKeyToValueMapping(KEY_NOTE,
                DynamicDataBuilders.DynamicDataValue.fromString("Note about day"))
        .build();
        // ...
    
        return Futures.immediateFuture(Tile.Builder()
            // Set resources, timeline, and other tile properties.
            .setState(state)
            .build()
        );
    }
  3. เมื่อสร้างเลย์เอาต์ ให้ใช้ออบเจ็กต์ประเภท Dynamic* ในตำแหน่งที่ต้องการแสดงข้อมูลจากสถานะ นอกจากนี้ คุณยังเรียกใช้ animate() เพื่อแสดงภาพเคลื่อนไหวจากค่าก่อนหน้าเป็นค่าปัจจุบันได้ด้วย โดยทำดังนี้

    Kotlin

    DynamicInt32.from(KEY_WATER_INTAKE).animate()

    Java

    DynamicInt32.from(KEY_WATER_INTAKE).animate();
  4. นอกจากนี้ คุณยังอัปเดตสถานะด้วยค่าใหม่ได้หากจําเป็น ซึ่งอาจเป็นส่วนหนึ่งของ LoadAction ของการ์ด

    ในตัวอย่างนี้ ระบบจะอัปเดตค่าการดื่มน้ำเป็น 400

    Kotlin

    val loadAction = LoadAction.Builder()
        .setRequestState(
            State.Builder()
                .addKeyToValueMapping(
                    KEY_WATER_INTAKE,
                    DynamicDataBuilders.DynamicDataValue.fromInt(400)
                )
                .build()
        )
        .build()

    Java

    LoadAction loadAction = new LoadAction.Builder()
        .setRequestState(
            new State.Builder()
                .addKeyToValueMapping(
                    KEY_WATER_INTAKE,
                    DynamicDataBuilders.DynamicDataValue.fromInt(400)
                ).build()
        ).build();