Większość dodatków opartych na kartach jest tworzona przy użyciu wielu kart, które reprezentują różne „strony” interfejsu dodatku. Aby zapewnić użytkownikom wygodę, w dodatku należy stosować prostą i naturalną nawigację między kartami.
W dodatkach do Gmaila przejścia między różnymi kartami interfejsu są obsługiwane przez umieszczanie i usuwanie kart z pojedynczego stosu kart, przy czym Gmail wyświetla kartę znajdującą się na górze stosu.

Dodatki do Google Workspace wprowadzają strony główne i karty bez kontekstu. Aby obsługiwać karty kontekstowe i niekontekstowe, dodatki do Google Workspace mają wewnętrzny stos kart dla każdego z nich. Gdy dodatek zostanie otwarty w aplikacji hosta, uruchamia się odpowiednia funkcja homepageTrigger, która tworzy pierwszą kartę strony głównej w stosie (ciemnoniebieska karta „strona główna” na diagramie poniżej).
Jeśli homepageTrigger nie jest zdefiniowany, tworzona jest karta domyślna, która jest wyświetlana i umieszczana na stosie bez kontekstu. Pierwsza karta to karta główna.
Dodatek może tworzyć dodatkowe karty niezwiązane z kontekstem i umieszczać je na stosie (niebieskie „wypchnięte karty” na diagramie), gdy użytkownik porusza się po dodatku. Interfejs dodatku wyświetla kartę znajdującą się na górze stosu, więc dodawanie nowych kart do stosu zmienia wyświetlanie, a usuwanie kart ze stosu przywraca wyświetlanie poprzednich kart.
Jeśli dodatek ma zdefiniowany wyzwalacz kontekstowy, wywoływany jest on, gdy użytkownik znajdzie się w danym kontekście. Funkcja wyzwalająca tworzy kartę kontekstową, ale wyświetlanie interfejsu jest aktualizowane na podstawie DisplayStyle nowej karty:
- Jeśli wartość
DisplayStyletoREPLACE(wartość domyślna), karta kontekstowa (ciemnopomarańczowa karta „kontekstowa” na diagramie) zastępuje aktualnie wyświetlaną kartę. W ten sposób na stosie kart niekontekstowych powstaje nowy stos kart kontekstowych, a ta karta kontekstowa jest główną kartą stosu kontekstowego. - Jeśli
DisplayStylema wartośćPEEK, interfejs tworzy nagłówek, który pojawia się u dołu paska bocznego dodatku, nakładając się na bieżącą kartę. Nagłówek podglądu zawiera tytuł nowej karty i przyciski sterujące, które pozwalają użytkownikowi zdecydować, czy chce wyświetlić nową kartę. Jeśli klikną przycisk Wyświetl, karta zastąpi bieżącą kartę (jak opisano powyżej w przypadkuREPLACE).
Możesz tworzyć dodatkowe karty kontekstowe i przesuwać je na stos (żółte „przesunięte karty” na diagramie). Aktualizacja stosu kart powoduje zmianę interfejsu dodatku, który wyświetla kartę znajdującą się na samej górze. Jeśli użytkownik opuści kontekst, karty kontekstowe na stosie zostaną usunięte, a wyświetlacz zostanie zaktualizowany do najwyższej karty niekontekstowej lub strony głównej.
Jeśli użytkownik przejdzie do kontekstu, dla którego dodatek nie definiuje wyzwalacza kontekstowego, nie zostanie utworzona nowa karta, a bieżąca karta pozostanie wyświetlona.
Opisane poniżej działania Navigation dotyczą tylko kart z tego samego kontekstu. Na przykład działanie popToRoot()
na karcie kontekstowej powoduje zamknięcie wszystkich innych kart kontekstowych i nie wpływa na karty na stronie głównej.
Z kolei przycisk jest zawsze dostępny, aby użytkownik mógł przejść z kart kontekstowych do kart niekontekstowych.
Metody nawigacji
Możesz tworzyć przejścia między kartami, dodając lub usuwając karty ze stosów. Klasa Navigation udostępnia funkcje do umieszczania i usuwania kart ze stosów. Aby utworzyć skuteczną nawigację po kartach, skonfiguruj widżety tak, aby używały działań nawigacyjnych. Możesz jednocześnie przesuwać wiele kart, ale nie możesz usunąć początkowej karty strony głównej, która jest pierwszą kartą umieszczaną na stosie po uruchomieniu dodatku.
Aby przejść do nowej karty w odpowiedzi na interakcję użytkownika z widżetem, wykonaj te czynności:
- Utwórz obiekt
Actioni powiąż go ze zdefiniowaną przez siebie funkcją wywołania zwrotnego. - Wywołaj odpowiednią funkcję obsługi widżetu, aby ustawić
Actionw tym widżecie. - Zaimplementuj funkcję wywołania zwrotnego, która przeprowadza nawigację. Ta funkcja otrzymuje jako argument obiekt zdarzenia działania i musi wykonać te czynności:
- Utwórz
Navigationobiekt, aby zdefiniować zmianę karty. Pojedynczy obiektNavigationmoże zawierać wiele kroków nawigacji, które są wykonywane w kolejności, w jakiej zostały dodane do obiektu. - Utwórz obiekt
ActionResponseza pomocą klasyActionResponseBuilderi obiektuNavigation. - Zwróć utworzony obiekt
ActionResponse.
- Utwórz
Podczas tworzenia elementów sterujących nawigacją używasz tych funkcji obiektu Navigation:
| Funkcja | Opis |
|---|---|
Navigation.pushCard(Card) |
Przesuwa kartę na bieżący stos. Wymaga to najpierw pełnego utworzenia karty. |
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 wszystkie karty ze stosu z wyjątkiem karty głównej. W zasadzie resetuje stos kart. |
Navigation.popToNamedCard(String) |
Usuwa karty ze stosu, aż dotrze do karty o podanej nazwie lub do karty głównej stosu. Możesz przypisywać nazwy do kart za pomocą funkcji CardBuilder.setName(String). |
Navigation.updateCard(Card) |
Zastępuje bieżącą kartę, odświeżając jej wyświetlanie w interfejsie. |
Sprawdzone metody nawigacji
Jeśli interakcja lub zdarzenie użytkownika powinny spowodować ponowne renderowanie 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 użytkownika lub zdarzenie powinny spowodować ponowne renderowanie kart w innym kontekście, użyj ActionResponseBuilder.setStateChanged(), aby wymusić ponowne wykonanie dodatku w tych kontekstach.
Oto przykłady nawigacji:
- Jeśli interakcja lub zdarzenie zmienia stan bieżącej karty (np. dodanie zadania do listy zadań), użyj metody
updateCard(). - Jeśli interakcja lub zdarzenie dostarcza dodatkowych szczegółów lub zachęca użytkownika do podjęcia dalszych działań (np. kliknięcia tytułu produktu, aby wyświetlić więcej szczegółów, lub naciśnięcia przycisku, aby utworzyć nowe wydarzenie w Kalendarzu), użyj
pushCard()do wyświetlenia nowej strony, umożliwiając jednocześnie użytkownikowi opuszczenie jej za pomocą przycisku Wstecz. - Jeśli interakcja lub zdarzenie aktualizuje stan na poprzedniej karcie (np. aktualizuje tytuł elementu w widoku szczegółów), użyj kodu podobnego do
popCard(),popCard(),pushCard(previous)ipushCard(current), aby zaktualizować poprzednią i bieżącą kartę.
Odświeżanie kart
Dodatki do Google Workspace umożliwiają użytkownikom odświeżanie karty przez ponowne uruchomienie funkcji wyzwalacza Apps Script zarejestrowanej w pliku manifestu. Użytkownicy mogą odświeżać dane za pomocą pozycji menu dodatku:
Ta czynność jest automatycznie dodawana do kart generowanych przez funkcje wyzwalające homepageTrigger lub contextualTrigger, zgodnie z plikiem manifestu dodatku (elementy główne stosów kart kontekstowych i niekontekstowych).
Zwracanie wielu kart
Funkcje wywoływania na stronie głównej lub kontekstowego służą do tworzenia i zwracania pojedynczego obiektu Card lub tablicy obiektów Card, które są wyświetlane w interfejsie aplikacji.
Jeśli jest tylko jedna karta, jest ona dodawana do stosu bez kontekstu lub z kontekstem jako karta główna i wyświetlana w interfejsie aplikacji hosta.
Jeśli zwrócona tablica zawiera więcej niż 1 wbudowany obiektCard, aplikacja hostująca wyświetla nową kartę z listą nagłówków poszczególnych kart. Gdy użytkownik kliknie którykolwiek z tych nagłówków, interfejs wyświetli odpowiednią kartę.
Gdy użytkownik wybierze kartę z listy, zostanie ona przeniesiona na bieżący stos, a aplikacja hosta ją wyświetli. Przycisk przenosi użytkownika z powrotem do listy nagłówków kart.
Taki układ „płaskich” kart może się sprawdzić, jeśli dodatek nie wymaga przejść między tworzonymi kartami. W większości przypadków lepszym rozwiązaniem jest jednak bezpośrednie definiowanie przejść między kartami oraz sprawienie, aby funkcje strony głównej i wyzwalacza kontekstowego zwracały pojedynczy obiekt karty.
Przykład
Oto przykład, który pokazuje, jak utworzyć kilka kart z przyciskami nawigacyjnymi, które umożliwiają przełączanie się między nimi. Karty te można dodać do stosu kontekstowego lub niekontekstowego, umieszczając kartę zwróconą 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();
}