Większość dodatków opartych na kartach jest tworzonych za pomocą wielu kart, które reprezentują różne „strony” interfejsu dodatku. Aby zapewnić użytkownikom skuteczne działanie, zadbaj o prostą i naturalną nawigację między kartami w dodatku.
Pierwotnie w dodatkach do Gmaila przejścia między różnymi kartami interfejsu były obsługiwane przez przesuwanie kart do i z jednej grupy kart, a karta na szczycie grupy była wyświetlana przez Gmaila.
Dodatki do Google Workspace wprowadzają strony główne i karty niekontekstowe. Aby uwzględnić karty kontekstowe i niekontekstowe, dodatki Google Workspace mają wewnętrzną warstwę kart dla każdego z nich. Gdy w gospodarzu otwiera się dodatek, odpowiedni homepageTrigger
uruchamia pierwszą kartę strony głównej na stosie (ciemnoniebieska karta „strony głównej” na diagramie poniżej).
Jeśli nie zdefiniujesz parametru homepageTrigger
, zostanie utworzona karta domyślna, wyświetlona i przesunięta na stos niekontekstualny. Pierwsza karta to główna.
Twój dodatek może tworzyć dodatkowe karty bez kontekstu i umieszczać je w stosie (niebieskie „karty dodane” na diagramie) podczas poruszania się użytkownika po dodatku. Interfejs dodatku wyświetla kartę na wierzchu stosu, więc dodanie nowych kart do stosu zmienia wyświetlanie, a usunięcie kart ze stosu powoduje wyświetlenie poprzednich kart.
Jeśli Twój dodatek ma zdefiniowany wyzwalacz kontekstowy, wyzwalacz ten jest uruchamiany, gdy użytkownik wejdzie w ten kontekst. Funkcja wyzwalacza tworzy kartę kontekstową, ale wyświetlanie interfejsu jest aktualizowane na podstawie DisplayStyle
nowej karty:
- Jeśli wartość
DisplayStyle
toREPLACE
(domyślnie), karta kontekstowa (ciemnopomarańczowa „karta kontekstowa” na diagramie) zastępuje aktualnie wyświetlaną kartę. Spowoduje to uruchomienie nowego kontekstowego stosu kart na wierzchu niekontekstualnego stosu kart. Ta karta kontekstowa jest główną kartą kontekstowego stosu. - Jeśli
DisplayStyle
toPEEK
, 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 oraz przyciski, za pomocą których użytkownik może zdecydować, czy chce ją wyświetlić. Jeśli kliknie przycisk Wyświetl, karta zastąpi bieżącą kartę (jak opisano powyżej w przypadkuREPLACE
).
Możesz utworzyć dodatkowe karty kontekstowe i przesunąć je na stos (żółte „przesunięte karty” na diagramie). Zmiana zestawu kart powoduje zmianę interfejsu dodatku w taki sposób, aby wyświetlić kartę znajdującą się na samej górze. Jeśli użytkownik opuści kontekst, karty kontekstowe na stosie zostaną usunięte, a wyświetlanie zmieni się na najwyższą kartę bez kontekstu lub stronę główną.
Jeśli użytkownik wprowadzi kontekst, dla którego nie zdefiniowano kontekstowego wyzwalacza, nie zostanie utworzona nowa karta, a obecna karta pozostanie wyświetlona.
Opisane poniżej działania Navigation
mają wpływ tylko na karty z tego samego kontekstu. Na przykład popToRoot()
z karty kontekstowej powoduje tylko wyświetlenie wszystkich innych kart kontekstowych i nie wpływa na karty na stronie głównej.
Natomiast przycisk
jest zawsze dostępny, aby użytkownik mógł przejść z karty kontekstowej na kartę niekontekstualną.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 wstawiania i usuwania kart ze stosów. Aby zapewnić skuteczną nawigację po kartach, skonfiguruj widżety tak, aby używały czynności nawigacyjnych. Możesz jednocześnie dodawać i usuwać wiele kart, ale nie możesz usunąć pierwszej karty na stronie głównej, która jest dodawana do stosu po uruchomieniu dodatku.
Aby przejść do nowej karty w reakcji na interakcję użytkownika z widżetem:
- Utwórz obiekt
Action
i połącz go ze zdefiniowaną przez siebie funkcją wywołania zwrotnego. - Wywołaj odpowiednią funkcję obsługi widżetu, aby ustawić
Action
dla tego widżetu. - Zaimplementuj funkcję wywołania zwrotnego, która prowadzi nawigację. Ta funkcja otrzymuje jako argument obiekt zdarzenia działania i musi:
- Utwórz obiekt
Navigation
, aby zdefiniować zmianę karty. Pojedynczy obiektNavigation
może zawierać wiele kroków nawigacji, które są wykonywane w kolejności dodawania ich do obiektu. - Utwórz obiekt
ActionResponse
za pomocą klasyActionResponseBuilder
i obiektuNavigation
. - Zwracanie skompilowanego pliku:
ActionResponse
.
- Utwórz obiekt
Podczas tworzenia elementów sterujących nawigacją używasz tych funkcji obiektu Navigation
:
Funkcja | Opis |
---|---|
Navigation.pushCard(Card) |
Przesuwa kartę na bieżącą warstwę. Wymaga to utworzenia karty. |
Navigation.popCard() |
Usuwa jedną kartę z góry stosu. To działanie jest równoważne kliknięciu strzałki wstecz w wierszu nagłówka dodatku. Nie spowoduje to usunięcia kart głównych. |
Navigation.popToRoot() |
usuwa wszystkie karty ze stosu oprócz karty głównej. Zasadniczo powoduje to zresetowanie stosu kart. |
Navigation.popToNamedCard(String) |
Wyjmuje karty ze stosu, aż dojdzie do karty o określonej nazwie lub do karty głównej stosu. Nazwy kart możesz przypisać za pomocą funkcji CardBuilder.setName(String) . |
Navigation.updateCard(Card) |
Czy zastępuje bieżącą kartę, odświeżając jej wyświetlanie w interfejsie. |
Sprawdzone metody dotyczące nawigacji
Jeśli interakcja z użytkownikiem lub zdarzenie powinno spowodować ponowne wyrenderowanie 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 z użytkownikiem lub zdarzenie powinno skutkować ponownym renderowaniem 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. dodając zadanie do listy zadań), użyj
updateCard()
. - Jeśli interakcja lub zdarzenie zawiera więcej szczegółów lub zachęca użytkownika do podjęcia dalszych działań (np. do kliknięcia tytułu elementu, aby wyświetlić więcej szczegółów, lub do naciśnięcia przycisku, aby utworzyć nowe zdarzenie w kalendarzu), użyj
pushCard()
, aby wyświetlić nową stronę, i pozwal użytkownikowi na jej opuszczenie za pomocą przycisku Wstecz. - Jeśli interakcja lub zdarzenie aktualizuje stan w poprzedniej karcie (np. zaktualizowanie tytułu elementu w widoku szczegółowym), użyj tagów takich jak
popCard()
,popCard()
,pushCard(previous)
ipushCard(current)
, aby zaktualizować poprzednią i bieżącą kartę.
Odświeżanie kart
Dodatki Google Workspace umożliwiają użytkownikom odświeżanie karty przez ponowne uruchomienie funkcji Apps Script zarejestrowanej w pliku manifestu. Użytkownicy inicjują to odświeżanie za pomocą pozycji menu dodatku:
To działanie jest automatycznie dodawane do kart generowanych przez funkcje wyzwalacza homepageTrigger
lub contextualTrigger
, zgodnie z opisem w pliku manifestu dodatku (elementy podstawowe skontekstualizowanych i nieskontekstualizowanych zestawów kart).
Zwracanie wielu kart
Funkcje strony głównej lub kontekstowego wyzwalacza służą do tworzenia i zwracania obiektu Card
lub tablicy obiektów Card
, które wyświetla interfejs użytkownika aplikacji.
Jeśli jest tylko 1 karta, jest ona dodawana do niekontekstualnego lub kontekstualnego stosu jako karta główna i wyświetlana w interfejsie aplikacji hosta.
Jeśli zwrócony tablica zawiera więcej niż jeden obiekt Card
, aplikacja hostująca wyświetla nową kartę zawierającą listę nagłówków każdej karty. Gdy użytkownik kliknie dowolny z tych nagłówków, interfejs wyświetli odpowiednią kartę.
Gdy użytkownik wybierze kartę z listy, zostanie ona dodana do bieżącego stosu, a aplikacja hostująca ją wyświetli. Przycisk
powoduje powrót użytkownika do listy nagłówków kart.Takie „płaskie” rozmieszczenie kart może się sprawdzić, jeśli dodatek nie wymaga żadnych przejść między tworzonymi kartami. W większości przypadków lepiej jest jednak definiować bezpośrednio przejścia między kartami, a funkcje strony głównej i kontekstualnych wyzwalaczy powinny zwracać pojedynczy obiekt karty.
Przykład
Oto przykładowy sposób tworzenia kilku kart z przyciskami nawigacyjnymi umożliwiającymi przełączanie się między nimi. Te karty można dodać do stosu kontekstowego lub niekontekstualnego, przesuwając kartę zwróconą przez createNavigationCard()
w ramach określonego kontekstu 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();
}