Nawigacja na kartach

Większość dodatków opartych na kartach składa się z wielu kart, które reprezentują różne „strony” interfejsu dodatku. Aby zadbać o wygodę użytkowników, należy korzystać z prostej i naturalnej nawigacji między kartami w dodatku.

Początkowo w dodatkach do Gmaila przejście między różnymi kartami w interfejsie odbywa się przez przesuwanie i wysuwanie kart do jednego stosu kart oraz z jednego stosu, a w Gmailu wyświetla się górna karta.

Nawigacja po karcie na stronie głównej

Dodatki do Google Workspace wprowadzają strony główne i karty niekontekstowe. Aby zapewnić obsługę kart kontekstowych i niekontekstowych, dodatki do Google Workspace mają wewnętrzny stos kart. Po otwarciu dodatku na hoście uruchamiany jest odpowiedni element homepageTrigger, który powoduje utworzenie pierwszej karty strony głównej w stosie (ciemnoniebieska karta „strona główna” na schemacie poniżej). Jeśli nie zdefiniowano homepageTrigger, zostanie utworzona, wyświetlona karta domyślna i przekazana do stosu niekontekstowego. Pierwsza karta jest kartą root.

Dodatek może tworzyć dodatkowe karty niezwiązane z kontekstem i przenosić je na stos (niebieskie „przesunięte karty” na diagramie), gdy użytkownik korzysta z dodatku. Interfejs dodatku wyświetla górną kartę na stosie, dlatego umieszczenie nowych kart w stosie zmienia widok, a wysunięcie kart ze stosu powoduje przywrócenie poprzedniego widoku.

Jeśli dodatek ma zdefiniowany regułę kontekstową, uruchamia się ona, gdy użytkownik wpisze ten kontekst. Funkcja aktywatora tworzy kartę kontekstową, ale widok interfejsu jest aktualizowany na podstawie danych DisplayStyle nowej karty:

  • Jeśli DisplayStyle to REPLACE (domyślna), karta kontekstowa (ciemnopomarańczowa karta „Kontekstowa” na diagramie) zastępuje aktualnie wyświetlaną kartę. Spowoduje to uruchomienie nowego stosu kart kontekstowych na stosie kart kontekstowych. Ta karta kontekstowa jest kartą główną stosu kontekstu.
  • Jeśli DisplayStyle to PEEK, interfejs tworzy wysunięty nagłówek, który wyświetla się u dołu paska bocznego dodatku, nakładając na bieżącą kartę. Nagłówek podglądu zawiera tytuł nowej karty i przyciski użytkownika, które pozwalają mu zdecydować, czy wyświetlić nową kartę. Jeśli kliknie przycisk Wyświetl, karta zastąpi bieżącą kartę (jak opisano powyżej REPLACE).

Możesz utworzyć dodatkowe karty kontekstowe i wypchnąć je na stos (żółte „przesunięte karty” na diagramie). Zaktualizowanie stosu kart powoduje zmianę interfejsu dodatku w taki sposób, że karta wyświetla się najwyżej. Jeśli użytkownik opuści kontekst, karty kontekstowe znajdujące się na stosie zostaną usunięte, a wyświetlona zostanie stworzona u góry karta niekontekstowa lub strona główna.

Jeśli użytkownik wprowadzi kontekst, w przypadku którego dodatek nie definiuje wyzwalacza kontekstowego, nie zostanie utworzona nowa karta, a obecna karta pozostanie wyświetlona.

Opisane poniżej działania Navigation działają tylko na kartach z tego samego kontekstu, np. popToRoot() z poziomu karty kontekstowej otwiera tylko pozostałe karty kontekstowe i nie będzie mieć wpływu na karty strony głównej.

W przeciwieństwie do tego za pomocą przycisku użytkownik zawsze może przejść z kart kontekstowych do kart niekontekstowych.

Możesz tworzyć przejścia między kartami, dodając karty do stosu lub usuwając je. Klasa Navigation zawiera funkcje do wypychania i wypychania kart ze stosu. Aby usprawnić nawigację po kartach, skonfigurujesz widżety tak, by korzystały z działań nawigacyjnych. Możesz umieścić lub umieścić kilka kart jednocześnie, ale nie możesz usunąć pierwszej karty ze strony głównej, która została najpierw przekazywana na stos podczas uruchamiania dodatku.

Aby przejść na nową kartę w odpowiedzi na interakcję użytkownika z widżetem, wykonaj te czynności:

  1. Utwórz obiekt Action i powiąż go ze zdefiniowaną przez siebie funkcją wywołania zwrotnego.
  2. Wywołaj odpowiednią funkcję obsługi widżetu, aby ustawić Action w tym widżecie.
  3. Zaimplementuj funkcję wywołania zwrotnego, która przeprowadza nawigację. Ta funkcja otrzymuje jako argument obiekt zdarzenia akcji i musi wykonać te czynności:
    1. Utwórz obiekt Navigation, aby zdefiniować zmianę karty. Pojedynczy obiekt Navigation może zawierać wiele etapów nawigacji, które są przeprowadzane w kolejności, w jakiej są dodawane do obiektu.
    2. Utwórz obiekt ActionResponse za pomocą klasy ActionResponseBuilder i obiektu Navigation.
    3. Zwróć utworzony ActionResponse.

Podczas tworzenia elementów sterujących nawigacji używasz tych funkcji obiektów Navigation:

Funkcja Opis
Navigation.pushCard(Card) Przesuwa kartę na bieżący stos. Najpierw musisz całkowicie utworzyć kartę.
Navigation.popCard() Usuwa jedną kartę z góry stosu. Odpowiednik kliknięcia strzałki wstecz w wierszu nagłówka dodatku. Nie spowoduje to usunięcia kart głównych.
Navigation.popToRoot() Usuwa ze stosu wszystkie karty oprócz karty głównej. Zasadniczo resetuje stos kart.
Navigation.popToNamedCard(String) Odrzuca karty ze stosu, aż dotrą do karty o podanej nazwie lub karcie głównej. Możesz przypisać nazwy do kart za pomocą funkcji CardBuilder.setName(String).
Navigation.updateCard(Card) Wykonuje zastąpienie bieżącej karty, odświeżając jej wyświetlanie w interfejsie.

Jeśli interakcja lub zdarzenie użytkownika powinny skutkować ponownym renderowaniem kart w tym samym kontekście, użyj metod Navigation.pushCard(), Navigation.popCard() i Navigation.updateCard(), aby zastąpić istniejące karty. Jeśli interakcja lub zdarzenie użytkownika powinny spowodować ponowne renderowanie kart w innym kontekście, użyj opcji ActionResponseBuilder.setStateChanged(), aby wymusić ponowne uruchomienie dodatku w takich kontekstach.

Oto przykłady nawigacji:

  • Jeśli interakcja lub zdarzenie zmienia stan bieżącej karty (np. przez dodanie zadania do listy zadań), użyj metody updateCard().
  • Jeśli interakcja lub wydarzenie zawiera bardziej szczegółowe informacje lub zachęca użytkownika do wykonania dalszego działania (na przykład przez kliknięcie tytułu elementu w celu wyświetlenia szczegółów albo naciśnięcie przycisku w celu utworzenia nowego wydarzenia w Kalendarzu), użyj opcji pushCard(), aby wyświetlić nową stronę i jednocześnie opuścić nową stronę przy użyciu przycisku Wstecz.
  • Jeśli interakcja lub zdarzenie aktualizuje stan na poprzedniej karcie (na przykład przez zmianę tytułu elementu z widoku szczegółów), użyj polecenia w rodzaju popCard(), popCard(), pushCard(previous) i pushCard(current), aby zaktualizować poprzednią i obecną kartę.

Odświeżanie kart

Dodatki do Google Workspace umożliwiają użytkownikom odświeżenie karty przez ponowne uruchomienie funkcji aktywatora Apps Script zarejestrowanej w pliku manifestu. Użytkownicy wywołują to odświeżenie za pomocą pozycji menu dodatku:

Pasek boczny dodatku Google Workspace

To działanie jest automatycznie dodawane do kart wygenerowanych przez funkcje aktywujące homepageTrigger lub contextualTrigger zgodnie z plikiem manifestu dodatku (czyli „główne” stosów kart kontekstowych i niekontekstowych).

Zwracanie wielu kart

Przykładowa karta dodatku

Strona główna lub funkcje aktywatora kontekstowego służą do tworzenia i zwracania pojedynczego obiektu Card lub tablicy obiektów Card wyświetlanych w interfejsie aplikacji.

Jeśli istnieje tylko 1 karta, jest ona dodawana do stosu niekontekstowego lub kontekstowego w ramach karty głównej i w interfejsie aplikacji hosta.

Jeśli zwrócona tablica zawiera więcej niż 1 skompilowany obiekt Card, aplikacja hosta wyświetli nową kartę z listą nagłówków każdej karty. Gdy użytkownik kliknie dowolny z tych nagłówków, w interfejsie wyświetli się odpowiednia karta.

Gdy użytkownik wybierze kartę z listy, jest ona przekazywana do bieżącego stosu, a aplikacja hostująca ją wyświetla. Przycisk przenosi użytkownika do listy nagłówków karty.

Taki „płaski” układ kart może się sprawdzić, gdy dodatek nie wymaga żadnych przejścia między utworzonymi przez Ciebie kartami. W większości przypadków lepiej jest jednak bezpośrednio definiować przejścia kart i poczekać, aby funkcje aktywatorów na stronie głównej i powiązane z regułami wywoływały 1 obiekt karty.

Przykład

Oto przykład, który pokazuje, jak utworzyć kilka kart za pomocą przycisków nawigacyjnych, które przełączają między nimi. Karty te można dodać do stosu kontekstowego lub niekontekstowego, wypychając kartę zwracaną przez createNavigationCard() w określonym kontekście lub poza nim.

  /**
   *  Create the top-level card, with buttons leading to each of three
   *  'children' cards, as well as buttons to backtrack and return to the
   *  root card of the stack.
   *  @return {Card}
   */
  function createNavigationCard() {
    // Create a button set with actions to navigate to 3 different
    // 'children' cards.
    var buttonSet = CardService.newButtonSet();
    for(var i = 1; i <= 3; i++) {
      buttonSet.addButton(createToCardButton(i));
    }

    // Build the card with all the buttons (two rows)
    var card = CardService.newCardBuilder()
        .setHeader(CardService.newCardHeader().setTitle('Navigation'))
        .addSection(CardService.newCardSection()
            .addWidget(buttonSet)
            .addWidget(buildPreviousAndRootButtonSet()));
    return card.build();
  }

  /**
   *  Create a button that navigates to the specified child card.
   *  @return {TextButton}
   */
  function createToCardButton(id) {
    var action = CardService.newAction()
        .setFunctionName('gotoChildCard')
        .setParameters({'id': id.toString()});
    var button = CardService.newTextButton()
        .setText('Card ' + id)
        .setOnClickAction(action);
    return button;
  }

  /**
   *  Create a ButtonSet with two buttons: one that backtracks to the
   *  last card and another that returns to the original (root) card.
   *  @return {ButtonSet}
   */
  function buildPreviousAndRootButtonSet() {
    var previousButton = CardService.newTextButton()
        .setText('Back')
        .setOnClickAction(CardService.newAction()
            .setFunctionName('gotoPreviousCard'));
    var toRootButton = CardService.newTextButton()
        .setText('To Root')
        .setOnClickAction(CardService.newAction()
            .setFunctionName('gotoRootCard'));

    // Return a new ButtonSet containing these two buttons.
    return CardService.newButtonSet()
        .addButton(previousButton)
        .addButton(toRootButton);
  }

  /**
   *  Create a child card, with buttons leading to each of the other
   *  child cards, and then navigate to it.
   *  @param {Object} e object containing the id of the card to build.
   *  @return {ActionResponse}
   */
  function gotoChildCard(e) {
    var id = parseInt(e.parameters.id);  // Current card ID
    var id2 = (id==3) ? 1 : id + 1;      // 2nd card ID
    var id3 = (id==1) ? 3 : id - 1;      // 3rd card ID
    var title = 'CARD ' + id;

    // Create buttons that go to the other two child cards.
    var buttonSet = CardService.newButtonSet()
      .addButton(createToCardButton(id2))
      .addButton(createToCardButton(id3));

    // Build the child card.
    var card = CardService.newCardBuilder()
        .setHeader(CardService.newCardHeader().setTitle(title))
        .addSection(CardService.newCardSection()
            .addWidget(buttonSet)
            .addWidget(buildPreviousAndRootButtonSet()))
        .build();

    // Create a Navigation object to push the card onto the stack.
    // Return a built ActionResponse that uses the navigation object.
    var nav = CardService.newNavigation().pushCard(card);
    return CardService.newActionResponseBuilder()
        .setNavigation(nav)
        .build();
  }

  /**
   *  Pop a card from the stack.
   *  @return {ActionResponse}
   */
  function gotoPreviousCard() {
    var nav = CardService.newNavigation().popCard();
    return CardService.newActionResponseBuilder()
        .setNavigation(nav)
        .build();
  }

  /**
   *  Return to the initial add-on card.
   *  @return {ActionResponse}
   */
  function gotoRootCard() {
    var nav = CardService.newNavigation().popToRoot();
    return CardService.newActionResponseBuilder()
        .setNavigation(nav)
        .build();
  }