التفاعل مع الشاشات

يمكن أن تؤدي المربّعات أكثر من مجرد عرض المعلومات، ويمكن أن تكون تفاعلية أيضًا. لجعل عنصر مثل textButton() يستجيب للنقرات، أنشئ معالجًا للنقر باستخدام clickable() واربطه بعنصر التنسيق.

يمكنك ضبط Clickable لبدء إجراء بطريقتَين رئيسيتين:

  1. بدء نشاط مباشرةً: استخدِم launchAction() في الحالات التي تحتاج فيها إلى فتح نشاط على الفور.
  2. تفويض خدمة مربّعات البيانات: استخدِم loadAction() لتشغيل المنطق داخل TileService. وهذا الأسلوب أكثر مرونة، إذ يتيح لك تحديث محتوى المربّع أو تعديل حالته أو بدء نشاط أكثر تعقيدًا.

تشغيل نشاط تم تصديره

إذا كان من المفترض أن يؤدي نقر المستخدم إلى بدء نشاط على الفور، استخدِم الرمز launchAction(). قدِّم ComponentName لتحديد النشاط. يجب تصدير النشاط. باستخدام هذا النهج، يمكنك تمرير Intent عنصر إضافي مع الإجراء. ومع ذلك، لا يمكن ضبط علامات Intent مخصّصة.

يوضّح المثال التالي كيفية إنشاء Clickable لبدء TileActivity مع عنصرَين إضافيَّين، name وage:

textButton(
    labelContent = {
        text("launchAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        launchAction(
            ComponentName(
                "com.example.wear",
                "com.example.wear.snippets.m3.tile.TileActivity",
            ),
            mapOf(
                "name" to ActionBuilders.stringExtra("Bartholomew"),
                "age" to ActionBuilders.intExtra(21),
            ),
        )
    ),
)

داخل النشاط الذي تم تشغيله، استرجع القيم من البيانات الإضافية للنشاط:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // When this activity is launched from the tile InteractionLaunchAction,
    // "name" will be "Bartholomew" and "age" will be 21
    val name = intent.getStringExtra("name")
    val age = intent.getStringExtra("age")

    // ...
}

معالجة التفاعلات في خدمة عرض الصور المصغّرة

للحصول على تفاعلات أكثر مرونة، استخدِم loadAction(). عندما ينقر مستخدم على أحد العناصر التي تم ضبطها باستخدام loadAction، يعيد النظام استدعاء TileService.onTileRequest(). يتيح لك ذلك تنفيذ منطق في خدمتك لتعديل المربّع وتغيير حالته وتنفيذ مهام أكثر تعقيدًا.

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

إنّ أبسط استخدام لرمز loadAction هو الإشارة إلى إعادة تحميل الصفحة. استدعاء loadAction بدون وسيطات عند النقر على العنصر، يطلب النظام onTileRequest()، ما يسمح لخدمتك بعرض تنسيق جديد يتضمّن محتوى معدَّلاً.

textButton(
    onClick = clickable(loadAction()),
    labelContent = { text("Refresh".layoutString) },
)

التمييز بين عناصر تفاعلية متعددة

إذا كان مربّع الرموز يحتوي على عناصر تفاعلية متعددة، يمكنك ربط معرّف بالمعدِّل Clickable:

في onTileRequest()، يمكنك التحقّق من رقم التعريف هذا باستخدام requestParams.currentState.lastClickableId لتحديد الإجراء الذي يجب اتّخاذه.

مثال: بدء نشاط باستخدام رابط لصفحة في التطبيق

هذا النمط مثالي لبدء نشاط باستخدام رابط لصفحة معيّنة. يؤدي انقر المستخدم إلى إعادة تحميل المربّع، وتفحص خدمتك رقم التعريف، ثم تبدأ النشاط الجديد. للتحكّم في الحزمة الخلفية، استخدِم TaskStackBuilder لتوفير تجربة تنقّل أفضل للمستخدم. عندما ينقر المستخدم على العنصر، يتم نقله مباشرةً إلى الشاشة التي تتضمّن رابطًا لصفحة معيّنة (شاشة message_detail/1 من المثال). وبما أنّه تم استخدام .addNextIntentWithParentStack()، تتم أيضًا إضافة النشاط الرئيسي إلى حزمة التطبيقات التي تم الخروج منها. وهذا يعني أنّه إذا مرّر المستخدم يده للخلف، سينتقل إلى الشاشة الرئيسية للتطبيق (MessageList في المثال ) بدلاً من الخروج مباشرةً إلى مربّع التطبيق. يؤدي التمرير سريعًا للخلف مرة ثانية إلى إعادة عرض التطبيق في مربّع التطبيق.

بعد ذلك، في TileActivity، اضبط التنقّل ليطابق نمط googleandroidsnippets://app/message_detail/{id}.

استخدِم TaskStackBuilder لتوفير تجربة تنقّل أفضل للمستخدم. عندما ينقر المستخدم على العنصر، يتم نقله مباشرةً إلى شاشة الرابط لصفحة في التطبيق، وفي هذا المثال، هي شاشة message_detail/1. بسبب استخدام .addNextIntentWithParentStack()، تتم أيضًا إضافة النشاط الرئيسي إلى الحزمة الخلفية. وهذا يعني أنّه إذا مرّر المستخدم سريعًا للخلف، سينتقل إلى الشاشة الرئيسية للتطبيق (MessageList في المثال) بدلاً من الخروج مباشرةً إلى المربّع. يؤدي التمرير سريعًا للخلف مرة ثانية إلى إعادة العنصر إلى مربّعه.

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

يحتوي مربّع الرموز على عنصر StateBuilders.State يخزّن أزواج مفاتيح/قيم ويحفظها عند إعادة التحميل. يمكنك استخدام loadAction() لتعديل هذه الحالة عندما يتفاعل مستخدم مع المربّع.

لإجراء ذلك، مرِّر DynamicDataMap إلى loadAction() يحتوي على قيم state الجديدة.

textButton(
    labelContent = {
        text("loadAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        loadAction(
            dynamicDataMapOf(
                stringAppDataKey("name") mapTo "Javier",
                intAppDataKey("age") mapTo 37,
            )
        )
    ),
)

عندما يتم تنشيط onTileRequest() من خلال هذا الإجراء، يمكنك قراءة data المعدَّلة من requestParams.currentState.stateMap. يُعدّ ذلك مفيدًا للتفاعلات التي تعدّل البيانات مباشرةً في المربّع، مثل زيادة عداد أو تبديل أحد الإعدادات.

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {

    // When triggered by loadAction(), "name" will be "Javier", and "age" will
    // be 37.
    with(requestParams.currentState.stateMap) {
        val name = this[stringAppDataKey("name")]
        val age = this[intAppDataKey("age")]
    }

    // ...
}