La maggior parte dei componenti aggiuntivi basati su schede viene creata utilizzando più schede che rappresentano "pagine" diverse dell'interfaccia del componente aggiuntivo. Per un'esperienza utente efficace, devi utilizzare una navigazione semplice e naturale tra le schede del componente aggiuntivo.
Originariamente nei componenti aggiuntivi di Gmail, le transizioni tra diverse schede dell'interfaccia utente vengono gestite spostando e aprendo le schede da e verso un'unica pila di schede, in cui Gmail mostra la prima scheda della pila.
I componenti aggiuntivi di Google Workspace introducono
home page e
schede non contestuali. Per inserire schede contestuali e non contestuali,
i componenti aggiuntivi di Google Workspace dispongono di un insieme di schede interno
per ciascuno. Quando un componente aggiuntivo viene aperto
in un host, si attiva il homepageTrigger
corrispondente per creare la prima
scheda home page nell'elenco (la scheda "home page" di colore blu scuro nel diagramma di seguito).
Se non viene definito un homepageTrigger
, viene creata, visualizzata una scheda predefinita
e inserita nell'elenco non contestuale. Questa prima scheda è una scheda principale.
Il componente aggiuntivo può creare altre schede non contestuali e inserirle nell'elenco (le "schede blu" nel diagramma) mentre l'utente naviga nel componente aggiuntivo. L'interfaccia utente del componente aggiuntivo mostra la prima scheda nella pila, quindi se sposti nuove schede nella pila, la visualizzazione cambia e la visualizzazione delle schede fuori dalla pila ripristina le schede precedenti.
Se il tuo componente aggiuntivo ha un attivatore contestuale definito, l'attivatore si attiva quando l'utente inserisce tale contesto. La funzione trigger
crea la scheda contestuale, ma la visualizzazione della UI viene aggiornata in base alle
DisplayStyle
della nuova scheda:
- Se
DisplayStyle
èREPLACE
(il valore predefinito), la scheda contestuale (la scheda "contestuale" arancione scuro nel diagramma) sostituisce la scheda attualmente visualizzata. In questo modo, viene avviata una nuova serie di schede contestuali sopra la pila di schede non contestuali, che è la scheda principale della pila contestuale. - Se
DisplayStyle
èPEEK
, l'interfaccia utente crea invece un'intestazione visibile nella parte inferiore della barra laterale del componente aggiuntivo, sovrapposta alla scheda corrente. L'intestazione di visualizzazione mostra il titolo della nuova scheda e fornisce i controlli dei pulsanti dell'utente che consentono all'utente di decidere se visualizzare o meno la nuova scheda. Se fa clic sul pulsante Visualizza, la scheda sostituisce la scheda corrente (come descritto sopra conREPLACE
).
Puoi creare schede contestuali aggiuntive e inserirle nell'elenco (le "schede gialle" nel diagramma). L'aggiornamento dell'elenco di schede cambia l'interfaccia utente del componente aggiuntivo in modo che mostri la scheda in alto. Se l'utente abbandona un contesto, le schede contestuali nell'elenco vengono rimosse e la visualizzazione viene aggiornata alla home page o alla scheda non contestuale più in alto.
Se l'utente inserisce un contesto per il quale il tuo componente aggiuntivo non definisce un attivatore contestuale, non viene creata una nuova scheda e la scheda corrente rimane visualizzata.
Le azioni Navigation
descritte di seguito agiscono solo sulle schede dello stesso contesto; ad esempio,
popToRoot()
da una scheda contestuale mostra solo tutte le altre schede contestuali e
non interessano le schede della home page.
Al contrario, il pulsante
è sempre disponibile per consentire all'utente di passare dalle schede contestuali alle schede non contestuali.Metodi di navigazione
Puoi creare transizioni tra le schede aggiungendo o rimuovendo le schede dai gruppi. La classe Navigation
fornisce funzioni per inviare e mostrare le schede dagli stack. Per creare
una navigazione delle schede efficace, devi configurare i
widget in modo da utilizzare
azioni di navigazione. Puoi inserire più schede contemporaneamente, ma non puoi rimuovere la scheda iniziale della home page che inizialmente viene inserita nell'elenco filtri quando viene avviato il componente aggiuntivo.
Per accedere a una nuova scheda in risposta a un'interazione dell'utente con un widget, procedi nel seguente modo:
- Crea un oggetto
Action
e associalo a una funzione di callback che definisci. - Chiama la funzione di gestore widget appropriata del widget per impostare
Action
su quel widget. - Implementa la funzione di callback che conduce la navigazione. A questa funzione viene assegnato un oggetto evento azione come argomento e deve:
- Crea un oggetto
Navigation
per definire la modifica della scheda. Un singolo oggettoNavigation
può contenere più passaggi di navigazione, che vengono eseguiti nell'ordine in cui vengono aggiunti all'oggetto. - Crea un oggetto
ActionResponse
utilizzando la classeActionResponseBuilder
e l'oggettoNavigation
. - Restituisci l'oggetto
ActionResponse
creato.
- Crea un oggetto
Quando crei i controlli di navigazione, puoi utilizzare le seguenti
funzioni degli oggetti Navigation
:
Funzione | Descrizione |
---|---|
Navigation.pushCard(Card) |
Invia una carta nella pila attuale. Devi prima creare la scheda completamente. |
Navigation.popCard() |
Rimuove una carta dalla parte superiore della pila. Equivale a fare clic sulla freccia indietro nella riga di intestazione del componente aggiuntivo. Le schede principali non vengono rimosse. |
Navigation.popToRoot() |
Rimuove tutte le schede dalla pila, ad eccezione della scheda root. In pratica, reimposta la pila di schede. |
Navigation.popToNamedCard(String) |
Scopre le carte dalla pila fino a quando non raggiunge una carta con il nome specificato o la carta principale della pila. Puoi assegnare i nomi alle schede utilizzando la funzione CardBuilder.setName(String) . |
Navigation.updateCard(Card) |
Consente di sostituire la carta corrente e di aggiornarne la visualizzazione nell'interfaccia utente. |
Best practice per la navigazione
Se un'interazione o un evento dell'utente dovrebbe comportare la visualizzazione di nuovo delle schede nello stesso contesto, utilizza i metodi Navigation.pushCard()
, Navigation.popCard()
e Navigation.updateCard()
per sostituire le schede esistenti. Se un'interazione o un evento dell'utente dovrebbe
portare a visualizzare nuovamente le schede in un contesto diverso, utilizza
ActionResponseBuilder.setStateChanged()
per forzare la riesecuzione del componente aggiuntivo in quei contesti.
Di seguito sono riportati alcuni esempi di navigazione:
- Se un'interazione o un evento modifica lo stato della scheda corrente (ad esempio,
aggiungendo un'attività a un elenco di attività), utilizza
updateCard()
. - Se un'interazione o un evento fornisce ulteriori dettagli o richiede all'utente
ulteriori azioni (ad esempio, fare clic sul titolo di un elemento per visualizzare ulteriori dettagli o
premere un pulsante per creare un nuovo evento di Calendar), utilizza
pushCard()
per mostrare la nuova pagina e consentire all'utente di uscire dalla nuova pagina utilizzando il pulsante Indietro. - Se lo stato di un'interazione o di un evento viene aggiornato in una scheda precedente (ad esempio,
l'aggiornamento del titolo di un elemento dalla visualizzazione dei dettagli), utilizza
popCard()
,popCard()
,pushCard(previous)
epushCard(current)
per aggiornare la carta precedente e quella corrente.
Aggiornamento delle schede in corso...
I componenti aggiuntivi di Google Workspace offrono agli utenti la possibilità di aggiornare la scheda eseguendo nuovamente la funzione trigger di Apps Script registrata nel file manifest. Gli utenti attivano questo aggiornamento tramite un componente aggiuntivo:
Questa azione viene aggiunta automaticamente alle schede generate dalle funzioni di attivazione di homepageTrigger
o
contextualTrigger
, come specificato nel file manifest
del componente aggiuntivo (le "root" degli insiemi di schede contestuali e non contestuali).
Restituzione di più carte
Le funzioni di trigger contestuale o sulla home page vengono utilizzate per creare e restituire un singolo oggetto Card
o un array di oggetti Card
visualizzati nell'interfaccia utente dell'applicazione.
Se è presente una sola scheda, questa viene aggiunta allo stack non contestuale o contestuale come scheda principale e nella UI dell'applicazione host.
Se l'array restituito include più oggetti Card
creati, l'applicazione host mostra invece una nuova scheda contenente un elenco dell'intestazione di ogni scheda. Quando l'utente fa clic su una di queste intestazioni, l'interfaccia utente mostra la scheda corrispondente.
Quando l'utente seleziona una scheda dall'elenco, questa viene inviata allo stack attuale e viene visualizzata dall'applicazione host. Il pulsante
riporta l'utente all'elenco delle intestazioni delle schede.Questa disposizione di schede "piatta" può essere efficace se il componente aggiuntivo non ha bisogno di transizioni tra le carte che crei. Nella maggior parte dei casi, tuttavia, è consigliabile definire direttamente le transizioni delle schede e fare in modo che la home page e le funzioni di attivazione contestuale restituiscano un singolo oggetto scheda.
Esempio
Ecco un esempio che mostra come creare diverse schede con pulsanti di navigazione
che consentono di passare da una all'altra. Queste schede possono essere aggiunte alla pila contestuale o non contestuale spingendo la scheda restituita da createNavigationCard()
all'interno o all'esterno di un determinato contesto.
/**
* 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();
}