La mayoría de los complementos basados en tarjetas se crean usando múltiples tarjetas que representan diferentes "páginas" de los del complemento. Para tener una experiencia del usuario eficaz, Deberías usar una navegación simple y natural entre las tarjetas de tu complemento.
Originalmente, en los complementos de Gmail, las transiciones entre diferentes tarjetas de la IU son que se manejan con el empujoncito y la apertura de tarjetas hacia y desde una única pila de tarjetas, con la tarjeta superior de la pila que muestra Gmail.
Los complementos de Google Workspace presentan
páginas principales y
tarjetas no contextuales. Para adaptarte a tarjetas contextuales y no contextuales,
Los complementos de Google Workspace tienen una pila de tarjetas interna.
para cada una. Cuando se abre un complemento
en un host, se activa el homepageTrigger
correspondiente para crear el primer
tarjeta de la página principal en la pila (la tarjeta azul oscuro “página de inicio” en el siguiente diagrama).
Si no se define un homepageTrigger
, se crea una tarjeta predeterminada, se muestra
y se inserta en la pila no contextual. Esta primera tarjeta es raíz.
Tu complemento puede crear tarjetas no contextuales adicionales y enviarlas a la (las "tarjetas enviadas" de color azul en el diagrama) a medida que el usuario navega por tu complemento. La IU del complemento muestra la tarjeta superior en la pila, por lo que enviar tarjetas a la pila cambia la pantalla, y quitar las tarjetas de la pila devuelve mostrar tarjetas anteriores.
Si tu complemento tiene un
activador contextual,
Cuando el usuario ingresa a ese contexto, se activa el activador. La función de activación
compila la tarjeta contextual, pero la pantalla de la IU se actualiza según el
DisplayStyle
de la nueva tarjeta:
- Si el elemento
DisplayStyle
esREPLACE
(la opción predeterminada), la tarjeta contextual (el color naranja oscuro) “contextual” tarjeta del diagrama) reemplaza el valor actual la tarjeta que se muestra. Esto inicia de forma eficaz una nueva pila de tarjetas contextuales en la parte superior. de la pila de tarjetas no contextuales, y esta tarjeta contextual es la raíz de la pila contextual. - Si el elemento
DisplayStyle
esPEEK
, la IU crea en cambio un encabezado de visualización que aparece en el en la parte inferior de la barra lateral del complemento, superpuesta a la tarjeta actual. El encabezado de vista previa muestra el título de la nueva tarjeta y proporciona al usuario controles de botones que le permiten ellos deciden si ver la nueva tarjeta o no. Si hacen clic en el botón Ver la tarjeta reemplaza a la actual (como se describió anteriormente conREPLACE
).
Puedes crear más tarjetas contextuales y y colocarlas en la pila (las “tarjetas empujadas” amarillas en el diagrama). Actualizando la pila de tarjetas cambia la IU del complemento para mostrar la tarjeta que está en la parte superior. Si el usuario deja un contexto, se quitan las tarjetas contextuales de la pila y la pantalla actualizaciones de la tarjeta o página principal no contextual que se encuentra en la parte superior.
Si el usuario ingresa un contexto en el que tu complemento no define un contextual, no se crea ninguna tarjeta nueva, y el pero seguirá apareciendo.
Las acciones Navigation
según se describe a continuación, solo actúan sobre las tarjetas del mismo contexto. por ejemplo,
popToRoot()
desde una tarjeta contextual solo muestra todas las demás tarjetas contextuales.
esto no afectará las tarjetas de la página principal.
Por el contrario, el botón
está siempre disponible para que el usuario navegue desde tus tarjetas contextuales hasta tu tarjetas no contextuales.Métodos de navegación
Puedes crear transiciones entre tarjetas agregando o eliminando tarjetas de la
pilas de tarjetas. El Navigation
proporciona funciones para enviar y extraer tarjetas de las pilas. Para compilar
la navegación eficaz por tarjetas, configuras tu
widgets para usar la navegación
acciones. Puedes enviar o mostrar
varias tarjetas a la vez, pero no puedes eliminar la tarjeta inicial de la página principal
que se inserta por primera vez en la pila cuando se inicia el complemento.
Para navegar a una nueva tarjeta en respuesta a la interacción de un usuario con un widget, sigue estos pasos:
- Crea un objeto
Action
. y asociarlo con un función de devolución de llamada que definas. - Llama al sistema de alertas correspondiente
Función del controlador del widget
para configurar
Action
en ese widget. - Implementa la función de devolución de llamada que lleva a cabo la navegación. Esta función
recibe un objeto de evento de acción
como argumento y debe hacer lo siguiente:
- Crea un
Navigation
. para definir el cambio de tarjeta. Un solo objetoNavigation
puede contienen varios pasos de navegación, que se realizan en el orden antes de que se agreguen al objeto. - Compila un
ActionResponse
con el comandoActionResponseBuilder
y laNavigation
. - Devuelve la compilación
ActionResponse
- Crea un
Cuando creas controles de navegación, usas lo siguiente
Funciones del objeto Navigation
:
Función | Descripción |
---|---|
Navigation.pushCard(Card) |
Envía una tarjeta a la pila actual. Para ello, primero debes compilar la tarjeta por completo. |
Navigation.popCard() |
Quita una tarjeta de la parte superior de la pila. El servicio equivale a hacer clic en la flecha hacia atrás de la fila del encabezado del complemento. Esta acción no quita las tarjetas raíz. |
Navigation.popToRoot() |
Quita todas las tarjetas de la pila, excepto la tarjeta raíz. Básicamente, restablece esa pila de tarjetas. |
Navigation.popToNamedCard(String) |
Muestra cartas de la pila hasta que llega a una con el nombre dado o a la tarjeta raíz de la pila. Puedes asignarles nombres a las tarjetas con la función CardBuilder.setName(String) . |
Navigation.updateCard(Card) |
Realiza un reemplazo in situ de la tarjeta actual y actualiza la pantalla en la IU. |
Práctica recomendada para la navegación
Si una interacción o un evento del usuario provoca que se vuelvan a renderizar las tarjetas en el mismo
contextual, usa
Navigation.pushCard()
:
Navigation.popCard()
,
y Navigation.updateCard()
para reemplazar las tarjetas existentes. Si una interacción o un evento del usuario
volver a renderizar las tarjetas en un contexto diferente, usa
ActionResponseBuilder.setStateChanged()
para forzar que se vuelva a ejecutar el complemento en esos contextos.
Los siguientes son ejemplos de navegación:
- Si una interacción o un evento cambia el estado de la tarjeta actual (por ejemplo,
agregar una tarea a una lista de tareas), usa
updateCard()
- Si una interacción o un evento proporciona más detalles o le pide al usuario que realice
acciones adicionales (por ejemplo, hacer clic en el título de un elemento para ver más detalles)
presiona un botón para crear un nuevo evento de Calendario), usa
pushCard()
para mostrar la página nueva y, a la vez, permitir que el usuario salga de ella con el botón Atrás. - Si una interacción o un evento actualiza el estado de una tarjeta anterior (por ejemplo,
actualizar el título de un elemento con la vista detallada), usa algo como
popCard()
:popCard()
,pushCard(previous)
, ypushCard(current)
. para actualizar la tarjeta anterior y la actual.
Actualizando tarjetas
Los complementos de Google Workspace ofrecen a los usuarios la posibilidad de hacer lo siguiente: actualiza la tarjeta; para ello, vuelve a ejecutar la función de activación de Apps Script registrada en tu manifiesto. Los usuarios activan esta actualización a través de un elemento de menú de complementos:
Esta acción se agrega automáticamente a las tarjetas generadas por homepageTrigger
o
Funciones de activador contextualTrigger
, como se especifica en el manifiesto de tu complemento
(las "raíces" de las pilas de tarjetas contextuales y no contextuales).
Cómo devolver varias tarjetas
La página principal o las funciones de activación contextuales se usan para compilar y mostrar
ya sea un solo
Card
o un array de
objetos Card
que la
la IU de la aplicación.
Si solo hay una tarjeta, se agrega a la pila no contextual o contextual. como la tarjeta raíz, y la IU de la aplicación host lo muestra.
Si el array que se muestra incluye más de un array
Card
objeto, la aplicación host muestra una nueva tarjeta, que contiene una
con la lista del encabezado de cada tarjeta. Cuando el usuario hace clic en cualquiera de esos encabezados, la IU
muestra la tarjeta correspondiente.
Cuando el usuario selecciona una tarjeta de la lista, esta se inserta en la pila actual y la aplicación host lo muestra. El El botón
lleva al usuario al lista de encabezados de tarjetas.Este plano la disposición de las tarjetas puede funcionar bien si el complemento no necesita las transiciones entre las tarjetas que creaste. Sin embargo, en la mayoría de los casos, es mejor practicar para definir directamente las transiciones de tarjetas, y tener la página de inicio y las funciones de activadores contextuales muestran un solo objeto de tarjeta.
Ejemplo
Este es un ejemplo que muestra cómo construir varias tarjetas con navegación
botones que se colocan entre ellos. Estas tarjetas se pueden agregar
una pila contextual o no contextual enviando la tarjeta que se muestra
por createNavigationCard()
dentro o fuera de un contexto particular.
/**
* 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();
}