Interakcja z kafelkami

Kafelki mogą nie tylko wyświetlać informacje, ale też być interaktywne. Aby element, np. textButton(), reagował na kliknięcia, wygeneruj metodę obsługi kliknięcia za pomocą elementu clickable() i połącz ją z elementem układu.

Możesz skonfigurować Clickable, aby wywoływało działanie na 2 główne sposoby:

  1. Uruchomienie aktywności bezpośrednio: kliknij launchAction(), gdy chcesz otworzyć aktywność natychmiast.
  2. Przekazywanie zadań do usługi kafelków: użyj funkcji loadAction(), aby wywołać logikę w TileService. Dzięki temu możesz odświeżać zawartość kafelka, aktualizować jego stan lub uruchamiać bardziej złożoną aktywność.

Uruchamianie wyeksportowanej aktywności

Jeśli kliknięcie przez użytkownika powinno natychmiast uruchamiać działanie, użyj launchAction(). Podaj wartość ComponentName, aby zidentyfikować aktywność. Aktywność musi zostać wyeksportowana. Dzięki temu możesz przekazać Intent elementy dodatkowe podczas działania. Nie można jednak ustawić niestandardowych flag Intent.

Z tego przykładu dowiesz się, jak utworzyć Clickable, aby uruchomić TileActivity z 2 dodatkami: nameage:

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),
            ),
        )
    ),
)

W uruchomionej aktywności pobierz wartości z intent extras:

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")

    // ...
}

Obsługa interakcji w usłudze kafelka

Aby umożliwić bardziej elastyczne interakcje, użyj elementu loadAction(). Gdy użytkownik kliknie element skonfigurowany za pomocą elementu loadAction, system ponownie wywoła funkcję TileService.onTileRequest(). Dzięki temu możesz uruchamiać w usłudze logikę, która aktualizuje kafelek, zmienia jego stan i wykonuje bardziej złożone zadania.

Odświeżanie zawartości kafelka

Najprostszym zastosowaniem elementu loadAction jest sygnalizowanie odświeżenia. Wywołaj funkcję loadAction bez argumentów. Po kliknięciu system wywołuje funkcję onTileRequest(), co pozwala Twojej usłudze zwrócić nowy układ z aktualnymi treściami.

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

Różnicowanie między wieloma elementami interaktywnymi

Jeśli kafelek zawiera wiele elementów interaktywnych, możesz powiązać identyfikator za pomocą modyfikatora Clickable:

onTileRequest() możesz sprawdzić ten identyfikator za pomocą requestParams.currentState.lastClickableId, aby podjąć decyzję, jakie działanie wykonać.

Przykład: uruchamianie aktywności za pomocą precyzyjnego linku

Ten schemat jest idealny do uruchamiania działań za pomocą precyzyjnego linku. Kliknięcie przez użytkownika powoduje ponowne załadowanie kafelka, a usługa sprawdza identyfikator i uruchamia nową aktywność. Aby kontrolować poziomy w steku, użyj elementu TaskStackBuilder, aby zapewnić użytkownikom lepszą nawigację. Gdy użytkownik kliknie element, zostanie przekierowany bezpośrednio na ekran z precyzyjnym linkiem (ekran message_detail/1 na przykładzie). Ponieważ użyto .addNextIntentWithParentStack(), aktywność nadrzędna jest również dodawana do stosu. Oznacza to, że jeśli użytkownik przesunie palcem w lewo, przejdzie do ekranu głównego aplikacji (MessageList na przykładzie), zamiast natychmiast zamknąć kafelek. Przesunięcie palcem w drugą stronę spowoduje powrót do kafelka.

Następnie w TileActivity skonfiguruj nawigację zgodnie ze wzorcem googleandroidsnippets://app/message_detail/{id}.

Aby ułatwić użytkownikom nawigację, użyj TaskStackBuilder. Gdy użytkownik kliknie element, zostanie przekierowany bezpośrednio na ekran z precyzyjnym linkiem. W tym przykładzie jest to ekran message_detail/1. Ponieważ użyto elementu .addNextIntentWithParentStack(), aktywność nadrzędna została również dodana do stosu. Oznacza to, że jeśli użytkownik przesunie palcem w lewo, przejdzie na ekran główny aplikacji (w tym przykładzie jest to MessageList), zamiast od razu wrócić na kafelek. Przesunięcie palcem w drugą stronę spowoduje powrót do kafelka.

Aktualizacja stanu na kafelku

Twoja kafelka ma obiekt StateBuilders.State, który przechowuje pary klucz-wartość i zachowuje się po ponownym załadowaniu. Aby zaktualizować ten stan, gdy użytkownik wejdzie w interakcję z płytką, możesz użyć loadAction().

Aby to zrobić, prześlij do loadAction() obiekt DynamicDataMap zawierający nowe wartości stanu.

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

Gdy to działanie spowoduje uruchomienie onTileRequest(), możesz odczytać zaktualizowane dane z requestParams.currentState.stateMap. Jest to przydatne w przypadku interakcji, które bezpośrednio modyfikują dane na kafelku, np. zwiększają licznik lub przełączają ustawienie.

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")]
    }

    // ...
}