Die meisten kartenbasierten Add-ons bestehen aus mehreren Karten, die verschiedene „Seiten“ der Add-on-Oberfläche darstellen. Für eine effektive Nutzererfahrung sollten Sie eine einfache und natürliche Navigation zwischen den Karten in Ihrem Add-on verwenden.
Ursprünglich wurden in Gmail-Add-ons Übergänge zwischen verschiedenen Karten der Benutzeroberfläche durch das Ein- und Ausblenden von Karten in einem einzelnen Kartenstapel gehandhabt. Die oberste Karte des Stapels wurde von Gmail angezeigt.

Mit Google Workspace-Add-ons werden Startseiten und nicht kontextbezogene Karten eingeführt. Für kontextbezogene und nicht kontextbezogene Karten gibt es in Google Workspace-Add‑ons jeweils einen internen Kartenstapel. Wenn ein Add-on in einem Host geöffnet wird, wird das entsprechende homepageTrigger ausgelöst, um die erste Startseitenkarte im Stapel zu erstellen (die dunkelblaue Karte „Startseite“ im Diagramm unten).
Wenn kein homepageTrigger definiert ist, wird eine Standardkarte erstellt, angezeigt und in den nicht kontextbezogenen Stapel eingefügt. Die erste Karte ist eine Stammkarte.
Ihr Add-on kann zusätzliche nicht kontextbezogene Karten erstellen und sie auf den Stapel (die blauen „pushed cards“ im Diagramm) legen, während der Nutzer durch Ihr Add-on navigiert. In der Add-on-Benutzeroberfläche wird die oberste Karte im Stapel angezeigt. Wenn Sie also neue Karten in den Stapel einfügen, ändert sich die Anzeige. Wenn Sie Karten aus dem Stapel entfernen, wird die Anzeige auf vorherige Karten zurückgesetzt.
Wenn Ihr Add-on einen definierten kontextbezogenen Trigger hat, wird der Trigger ausgelöst, wenn der Nutzer diesen Kontext aufruft. Die Triggerfunktion erstellt die Kontextkarte, die UI-Anzeige wird jedoch basierend auf dem DisplayStyle der neuen Karte aktualisiert:
- Wenn
DisplayStyleaufREPLACE(Standard) festgelegt ist, wird die aktuell angezeigte Karte durch die kontextbezogene Karte (die dunkelorangefarbene „kontextbezogene“ Karte im Diagramm) ersetzt. Dadurch wird effektiv ein neuer kontextbezogener Kartenstapel über dem nicht kontextbezogenen Kartenstapel gestartet. Diese kontextbezogene Karte ist die Stammkarte des kontextbezogenen Stapels. - Wenn
DisplayStylegleichPEEKist, wird in der Benutzeroberfläche stattdessen ein Header erstellt, der unten in der Add-on-Seitenleiste eingeblendet wird und die aktuelle Karte überlagert. In der Kopfzeile der Vorschau werden der Titel der neuen Karte und die Schaltflächen zur Steuerung angezeigt, mit denen der Nutzer entscheiden kann, ob er die neue Karte aufrufen möchte. Wenn sie auf die Schaltfläche Ansehen klicken, wird die aktuelle Karte durch die neue Karte ersetzt (wie oben beiREPLACEbeschrieben).
Sie können zusätzliche Kontextkarten erstellen und in den Stapel einfügen (die gelben „eingefügten Karten“ im Diagramm). Durch das Aktualisieren des Kartenstapels wird die Add-on-Benutzeroberfläche so geändert, dass die oberste Karte angezeigt wird. Wenn der Nutzer einen Kontext verlässt, werden die kontextbezogenen Karten im Stapel entfernt und die Anzeige wird auf die oberste nicht kontextbezogene Karte oder die Startseite aktualisiert.
Wenn der Nutzer einen Kontext eingibt, für den in Ihrem Add-on kein kontextbezogener Trigger definiert ist, wird keine neue Karte erstellt und die aktuelle Karte bleibt sichtbar.
Die unten beschriebenen Navigation-Aktionen wirken sich nur auf Karten aus demselben Kontext aus. Wenn Sie beispielsweise popToRoot() in einer Kontextkarte ausführen, werden nur alle anderen Kontextkarten entfernt, nicht aber die Karten auf der Startseite.
Die Schaltfläche ist dagegen immer verfügbar, damit Nutzer von Ihren kontextbezogenen Karten zu Ihren nicht kontextbezogenen Karten wechseln können.
Navigationsmethoden
Sie können Übergänge zwischen Karten erstellen, indem Sie Karten in den Kartenstapeln hinzufügen oder entfernen. Die Klasse Navigation bietet Funktionen zum Hinzufügen und Entfernen von Karten aus den Stapeln. Um eine effektive Kartennavigation zu erstellen, konfigurieren Sie Ihre Widgets so, dass sie Navigationsaktionen verwenden. Sie können mehrere Karten gleichzeitig einfügen oder entfernen, aber die erste Karte auf der Startseite, die beim Start des Add-ons in den Stapel eingefügt wird, kann nicht entfernt werden.
So navigieren Sie zu einer neuen Karte als Reaktion auf eine Nutzerinteraktion mit einem Widget:
- Erstellen Sie ein
Action-Objekt und verknüpfen Sie es mit einer Callback-Funktion, die Sie definieren. - Rufen Sie die entsprechende Widget-Handler-Funktion des Widgets auf, um die
Actionfür dieses Widget festzulegen. - Implementieren Sie die Callback-Funktion, die die Navigation ausführt. Diese Funktion erhält ein Aktionsereignisobjekt als Argument und muss Folgendes tun:
- Erstellen Sie ein
Navigation-Objekt, um die Kartenänderung zu definieren. Ein einzelnesNavigation-Objekt kann mehrere Navigationsschritte enthalten, die in der Reihenfolge ausgeführt werden, in der sie dem Objekt hinzugefügt wurden. - Erstellen Sie ein
ActionResponse-Objekt mit der KlasseActionResponseBuilderund dem ObjektNavigation. - Gibt den erstellten
ActionResponsezurück.
- Erstellen Sie ein
Beim Erstellen von Navigationssteuerelementen verwenden Sie die folgenden Navigation-Objektfunktionen:
| Funktion | Beschreibung |
|---|---|
Navigation.pushCard(Card) |
Legt eine Karte auf den aktuellen Stapel. Dazu muss die Karte zuerst vollständig erstellt werden. |
Navigation.popCard() |
Entfernt eine Karte von der Oberseite des Stapels. Entspricht dem Klicken auf den Zurückpfeil in der Kopfzeile des Add-ons. Stammkarten werden dadurch nicht entfernt. |
Navigation.popToRoot() |
Entfernt alle Karten aus dem Stapel mit Ausnahme der Stammkarte. Dadurch wird der Kartenstapel im Wesentlichen zurückgesetzt. |
Navigation.popToNamedCard(String) |
Entfernt Karten aus dem Stapel, bis eine Karte mit dem angegebenen Namen oder die Stammkarte des Stapels erreicht wird. Mit der Funktion CardBuilder.setName(String) können Sie Karten Namen zuweisen. |
Navigation.updateCard(Card) |
Die aktuelle Karte wird ersetzt und die Darstellung auf der Benutzeroberfläche aktualisiert. |
Best Practice für die Navigation
Wenn eine Nutzerinteraktion oder ein Ereignis dazu führen soll, dass Karten im selben Kontext neu gerendert werden, verwenden Sie die Methoden Navigation.pushCard(), Navigation.popCard() und Navigation.updateCard(), um die vorhandenen Karten zu ersetzen. Wenn eine Nutzerinteraktion oder ein Ereignis dazu führen soll, dass Karten in einem anderen Kontext neu gerendert werden, verwenden Sie ActionResponseBuilder.setStateChanged(), um die erneute Ausführung Ihres Add-ons in diesen Kontexten zu erzwingen.
Hier einige Beispiele für die Navigation:
- Wenn durch eine Interaktion oder ein Ereignis der Status der aktuellen Karte geändert wird (z. B. durch Hinzufügen einer Aufgabe zu einer Aufgabenliste), verwenden Sie
updateCard(). - Wenn eine Interaktion oder ein Ereignis weitere Details liefert oder den Nutzer zu einer weiteren Aktion auffordert (z. B. auf den Titel eines Elements klicken, um weitere Details aufzurufen, oder eine Schaltfläche drücken, um einen neuen Kalendertermin zu erstellen), verwenden Sie
pushCard(), um die neue Seite anzuzeigen und dem Nutzer gleichzeitig die Möglichkeit zu geben, die neue Seite über die Schaltfläche „Zurück“ zu verlassen. - Wenn durch eine Interaktion oder ein Ereignis der Status auf einer vorherigen Karte aktualisiert wird (z. B. wenn der Titel eines Elements über die Detailansicht aktualisiert wird), verwenden Sie
popCard(),popCard(),pushCard(previous)undpushCard(current), um die vorherige und die aktuelle Karte zu aktualisieren.
Karten werden aktualisiert
Mit Google Workspace-Add‑ons können Nutzer Ihre Karte aktualisieren, indem sie die in Ihrem Manifest registrierte Apps Script-Triggerfunktion noch einmal ausführen. Nutzer lösen diese Aktualisierung über einen Add-on-Menüpunkt aus:
Diese Aktion wird automatisch Karten hinzugefügt, die von homepageTrigger- oder contextualTrigger-Triggerfunktionen generiert werden, wie in der Manifestdatei Ihres Add-ons angegeben (die „Roots“ der kontextbezogenen und nicht kontextbezogenen Kartenstapel).
Mehrere Karten zurückgeben
Mit Funktionen für die Startseite oder kontextbezogene Trigger wird entweder ein einzelnes Card-Objekt oder ein Array von Card-Objekten erstellt und zurückgegeben, die in der Benutzeroberfläche der Anwendung angezeigt werden.
Wenn nur eine Karte vorhanden ist, wird sie als Stammkarte dem nicht kontextbezogenen oder kontextbezogenen Stapel hinzugefügt und in der Benutzeroberfläche der Hostanwendung angezeigt.
Wenn das zurückgegebene Array mehr als ein integriertes Card-Objekt enthält, wird in der Hostanwendung stattdessen eine neue Karte mit einer Liste der Header der einzelnen Karten angezeigt. Wenn der Nutzer auf einen dieser Header klickt, wird die entsprechende Karte in der Benutzeroberfläche angezeigt.
Wenn der Nutzer eine Karte aus der Liste auswählt, wird sie auf den aktuellen Stapel gelegt und in der Hostanwendung angezeigt. Über die Schaltfläche kehrt der Nutzer zur Liste der Kartenüberschriften zurück.
Diese „flache“ Kartenanordnung kann gut funktionieren, wenn für Ihr Add-on keine Übergänge zwischen den erstellten Karten erforderlich sind. In den meisten Fällen ist es jedoch besser, Kartenübergänge direkt zu definieren und die Funktionen für die Startseite und kontextbezogene Trigger ein einzelnes Kartenobjekt zurückgeben zu lassen.
Beispiel
Hier sehen Sie ein Beispiel dafür, wie Sie mehrere Karten mit Navigationsschaltflächen erstellen, mit denen zwischen den Karten gewechselt werden kann. Diese Karten können dem kontextbezogenen oder nicht kontextbezogenen Stapel hinzugefügt werden, indem die von createNavigationCard() zurückgegebene Karte in oder außerhalb eines bestimmten Kontextes gepusht wird.
/**
* 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();
}