بیشتر افزونههای مبتنی بر کارت با استفاده از کارتهای متعددی ساخته میشوند که «صفحات» متفاوت رابط افزونه را نشان میدهند. برای داشتن یک تجربه کاربری موثر، باید از ناوبری ساده و طبیعی بین کارت ها در افزونه خود استفاده کنید.
در اصل در افزونههای Gmail، انتقال بین کارتهای مختلف رابط کاربری با فشار دادن و باز کردن کارتها به و از یک پشته کارت انجام میشود، و کارت بالای پشته توسط Gmail نمایش داده میشود.
افزونههای Google Workspace صفحات اصلی و کارتهای غیر متنی را معرفی میکنند. برای قرار دادن کارتهای متنی و غیر متنی، افزونههای Google Workspace یک پشته کارت داخلی برای هر کدام دارد. هنگامی که یک افزونه در یک میزبان باز می شود، homepageTrigger
مربوطه فعال می شود تا اولین کارت صفحه اصلی در پشته ایجاد شود (کارت "صفحه اصلی" آبی تیره در نمودار زیر). اگر homepageTrigger
تعریف نشده باشد، یک کارت پیشفرض ایجاد میشود، نمایش داده میشود و روی پشته غیر متنی قرار میگیرد. این کارت اول یک کارت ریشه است.
افزونه شما میتواند کارتهای غیر متنی اضافی ایجاد کند و آنها را در پشته («کارتهای فشار داده شده» آبی رنگ در نمودار) در حالی که کاربر از طریق افزونه شما حرکت میکند، فشار دهد. رابط کاربری افزونه کارت بالایی را در پشته نمایش میدهد، بنابراین با فشار دادن کارتهای جدید به پشته، نمایشگر تغییر میکند و بیرون آمدن کارتها از پشته، نمایشگر را به کارتهای قبلی برمیگرداند.
اگر افزونه شما دارای یک محرک متنی تعریف شده باشد، وقتی کاربر وارد آن زمینه می شود، ماشه فعال می شود. تابع ماشه کارت متنی را می سازد، اما صفحه نمایش رابط کاربری بر اساس DisplayStyle
کارت جدید به روز می شود:
- اگر
DisplayStyle
REPLACE
باشد (پیشفرض)، کارت متنی (کارت متنی نارنجی تیره در نمودار) جایگزین کارت نمایش داده شده فعلی میشود. این به طور موثر یک پشته کارت متنی جدید را در بالای پشته کارت غیر متنی شروع می کند، و این کارت متنی کارت ریشه پشته متنی است. - اگر
DisplayStyle
PEEK
باشد، رابط کاربری در عوض یک سرصفحه زیرکانه ایجاد میکند که در پایین نوار کناری افزودنی ظاهر میشود و روی کارت فعلی قرار میگیرد. هدر peek عنوان کارت جدید را نشان می دهد و دکمه های کاربر را کنترل می کند که به آنها اجازه می دهد تصمیم بگیرند که کارت جدید را ببینند یا نه. اگر روی دکمه View کلیک کنند، کارت جایگزین کارت فعلی می شود (همانطور که در بالا باREPLACE
توضیح داده شد).
میتوانید کارتهای متنی اضافی ایجاد کنید و آنها را روی پشته فشار دهید («کارتهای هل داده شده» زرد در نمودار). بهروزرسانی پشته کارت، رابط کاربری افزونه را تغییر میدهد تا بالاترین کارت را نمایش دهد. اگر کاربر یک زمینه را ترک کند، کارتهای متنی موجود در پشته حذف میشوند و صفحه نمایش به بالاترین کارت غیر متنی یا صفحه اصلی بهروزرسانی میشود.
اگر کاربر زمینهای را وارد کند که افزونه شما برای آن یک محرک متنی تعریف نکرده باشد، کارت جدیدی ایجاد نمیشود و کارت فعلی نمایش داده میشود.
اقدامات Navigation
که در زیر توضیح داده شده است فقط روی کارت هایی از یک زمینه عمل می کنند. برای مثال، popToRoot()
از داخل یک کارت متنی، فقط همه کارت های متنی دیگر را باز می کند و روی کارت های صفحه اصلی تأثیری نخواهد داشت.
در مقابل، دکمه
همیشه برای کاربر در دسترس است تا از کارت های متنی شما به کارت های غیر متنی شما حرکت کند.روش های ناوبری
میتوانید با افزودن یا حذف کارتها از پشتههای کارت، انتقال بین کارتها ایجاد کنید. کلاس Navigation
توابعی برای فشار دادن و باز کردن کارت ها از پشته ها ارائه می کند. برای ایجاد ناوبری کارت موثر، ویجت های خود را برای استفاده از اقدامات پیمایش پیکربندی می کنید. میتوانید چندین کارت را بهطور همزمان فشار دهید یا باز کنید، اما نمیتوانید کارت صفحه اصلی اولیه را که برای اولین بار روی پشته فشار داده میشود، هنگام شروع افزونه حذف کنید.
برای پیمایش به کارت جدید در پاسخ به تعامل کاربر با ویجت، مراحل زیر را دنبال کنید:
- یک شی
Action
ایجاد کنید و آن را با تابع callback که تعریف کرده اید مرتبط کنید. - برای تنظیم
Action
روی آن ویجت ، تابع کنترل کننده ویجت مناسب ویجت را فراخوانی کنید. - عملکرد برگشت به تماس را که ناوبری را انجام می دهد، اجرا کنید. به این تابع به عنوان آرگومان یک شی رویداد action داده می شود و باید کارهای زیر را انجام دهد:
- یک شی
Navigation
برای تعریف تغییر کارت ایجاد کنید. یک شیNavigation
منفرد می تواند شامل چندین مرحله ناوبری باشد که به ترتیبی که به شی اضافه می شوند انجام می شوند. - با استفاده از کلاس
ActionResponseBuilder
و آبجکتNavigation
یک شیActionResponse
بسازید. -
ActionResponse
ساخته شده را برگردانید.
- یک شی
هنگام ساختن کنترلهای ناوبری، از توابع شی Navigation
زیر استفاده میکنید:
تابع | توضیحات |
---|---|
Navigation.pushCard(Card) | یک کارت را به پشته فعلی فشار می دهد. این نیاز به ساخت کارت به طور کامل ابتدا دارد. |
Navigation.popCard() | یک کارت را از بالای پشته حذف می کند. معادل کلیک بر روی فلش عقب در ردیف هدر افزونه است. این کارتهای ریشه را حذف نمیکند. |
Navigation.popToRoot() | تمام کارت ها را به جز کارت ریشه از پشته حذف می کند. اساساً پشته کارت را بازنشانی می کند. |
Navigation.popToNamedCard(String) | کارتها را از پشته بیرون میآورد تا به کارتی با نام مشخص شده یا کارت ریشه پشته برسد. با استفاده از تابع CardBuilder.setName(String) می توانید نام ها را به کارت ها اختصاص دهید. |
Navigation.updateCard(Card) | کارت فعلی را در جای خود جایگزین می کند و نمایشگر آن را در رابط کاربری تازه می کند. |
بهترین روش ناوبری
اگر تعامل یا رویدادی با کاربر منجر به رندر مجدد کارت ها در همان زمینه شود، از روش های Navigation.pushCard()
، Navigation.popCard()
و Navigation.updateCard()
برای جایگزینی کارت های موجود استفاده کنید. اگر تعامل یا رویدادی با کاربر منجر به رندر مجدد کارت ها در زمینه دیگری شود، از ActionResponseBuilder.setStateChanged()
برای اجبار اجرای مجدد افزونه خود در آن زمینه ها استفاده کنید.
نمونه های ناوبری زیر هستند:
- اگر یک تعامل یا رویداد وضعیت کارت فعلی را تغییر دهد (به عنوان مثال، اضافه کردن یک کار به یک لیست کار)، از
updateCard()
استفاده کنید. - اگر فعل و انفعال یا رویدادی جزئیات بیشتری را ارائه می دهد یا کاربر را برای اقدامات بیشتر ترغیب می کند (به عنوان مثال، کلیک کردن روی عنوان یک مورد برای دیدن جزئیات بیشتر، یا فشار دادن یک دکمه برای ایجاد یک رویداد تقویم جدید)، از
pushCard()
برای نمایش صفحه جدید استفاده کنید. به کاربر اجازه می دهد تا با استفاده از دکمه Back از صفحه جدید خارج شود. - اگر یک تعامل یا رویداد در کارت قبلی بهروزرسانی میشود (بهعنوان مثال، بهروزرسانی عنوان یک مورد با نمای جزئیات)، از چیزی مانند
popCard()
,popCard()
,pushCard(previous)
وpushCard(current)
برای بهروزرسانی قبلی استفاده کنید. کارت و کارت فعلی
کارت های با طراوت
افزونههای Google Workspace به کاربران این امکان را میدهند که کارت شما را با اجرای مجدد تابع راهاندازی Apps Script ثبتشده در مانیفست شما بهروزرسانی کنند. کاربران این بهروزرسانی را از طریق یک آیتم منوی افزودنی فعال میکنند:
این عملکرد به طور خودکار به کارتهای ایجاد شده توسط توابع آغازگر homepageTrigger
یا contextualTrigger
اضافه میشود، همانطور که در فایل مانیفست افزونه شما مشخص شده است («ریشههای» پشتههای کارت متنی و غیر متنی).
بازگرداندن چند کارت
توابع آغازگر صفحه اصلی یا متنی برای ایجاد و برگرداندن یک شی Card
یا آرایه ای از اشیاء Card
که رابط کاربری برنامه نمایش می دهد استفاده می شود.
اگر فقط یک کارت وجود داشته باشد، به پشته غیر متنی یا متنی به عنوان کارت ریشه اضافه می شود و UI برنامه میزبان آن را نمایش می دهد.
اگر آرایه برگشتی شامل بیش از یک شی Card
ساخته شده باشد، برنامه میزبان در عوض یک کارت جدید را نمایش می دهد که حاوی لیستی از هدر هر کارت است. هنگامی که کاربر روی هر یک از آن هدرها کلیک می کند، UI کارت مربوطه را نمایش می دهد.
هنگامی که کاربر کارتی را از لیست انتخاب می کند، آن کارت به پشته فعلی فشار داده می شود و برنامه میزبان آن را نمایش می دهد. دکمه
کاربر را به لیست سرصفحه کارت باز می گرداند.این چیدمان کارت «مسطح» میتواند به خوبی کار کند اگر افزونه شما به هیچ انتقالی بین کارتهایی که ایجاد میکنید نیاز نداشته باشد. با این حال، در بیشتر موارد، بهتر است مستقیماً انتقال کارت را تعریف کنید و صفحه اصلی و توابع ماشه متنی یک شی کارت را برگردانند.
مثال
در اینجا مثالی وجود دارد که نحوه ساخت چندین کارت را با دکمه های ناوبری که بین آنها پرش می کنند نشان می دهد. این کارتها را میتوان با فشار دادن کارت بازگردانده شده توسط createNavigationCard()
در داخل یا خارج از یک زمینه خاص، به پشته متنی یا غیر متنی اضافه کرد.
/**
* 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();
}