ส่วนเสริมแบบการ์ดส่วนใหญ่สร้างขึ้นโดยใช้การ์ดหลายรายการที่แสดงถึง "หน้า" ต่างๆ ของอินเทอร์เฟซส่วนเสริม หากต้องการมอบประสบการณ์ของผู้ใช้ที่มีประสิทธิภาพ คุณควรใช้การนำทางที่เรียบง่ายและเป็นธรรมชาติระหว่างการ์ดในส่วนเสริม
เดิมทีอยู่ในส่วนเสริมของ Gmail การเปลี่ยนระหว่างการ์ดต่างๆ ใน UI จะจัดการด้วยการพุชและเรียกการ์ดไปและกลับจากชุดการ์ดเดี่ยว โดยการ์ดบนสุดของกลุ่มการ์ดจะแสดงโดย Gmail
ส่วนเสริมของ Google Workspace จะเพิ่มหน้าแรกและการ์ดที่ไม่ใช่บริบท ส่วนเสริมของ Google Workspace จะมีสแต็กการ์ดภายในสำหรับแต่ละการ์ดเพื่อรองรับการ์ดตามบริบทและการ์ดที่ไม่ใช่บริบท เมื่อเปิดส่วนเสริมในโฮสต์ homepageTrigger
ที่เกี่ยวข้องจะเริ่มทำงานเพื่อสร้างการ์ดหน้าแรกรายการแรกในชุดรายการ (การ์ด "หน้าแรก" สีน้ำเงินเข้มในแผนภาพด้านล่าง)
หากไม่ได้กำหนด homepageTrigger
ระบบจะสร้างการ์ดเริ่มต้น แสดง และพุชไปยังสแต็กที่ไม่ใช่บริบท การ์ดแรกคือการ์ดรูท
ส่วนเสริมสามารถสร้างการ์ดที่ไม่ใช่บริบทเพิ่มเติม แล้วนำไปใส่ในกลุ่ม ("การ์ดแบบพุช" สีฟ้าในแผนภาพ) เมื่อผู้ใช้ไปยังส่วนต่างๆ ของส่วนเสริม UI ส่วนเสริมจะแสดงการ์ดบนสุดในกลุ่ม ดังนั้นการผลักดันการ์ดใหม่ไปยังสแต็กจะเป็นการเปลี่ยนการแสดงผล และการเปิดการ์ดจากสแต็กจะส่งคืนการ์ดไปยังการ์ดก่อนหน้า
หากส่วนเสริมมีทริกเกอร์ตามบริบทที่กำหนดไว้
ทริกเกอร์ก็จะเริ่มทำงานเมื่อผู้ใช้เข้าสู่บริบทนั้น ฟังก์ชันทริกเกอร์จะสร้างการ์ดบริบท แต่การแสดงผล UI จะอัปเดตตาม DisplayStyle
ของการ์ดใหม่ ดังนี้
- หาก
DisplayStyle
เป็นREPLACE
(ค่าเริ่มต้น) การ์ดบริบท (การ์ด "บริบท" สีส้มเข้มในแผนภาพ) จะแทนที่การ์ดที่แสดงอยู่ ซึ่งจะเป็นการเริ่มต้นสแต็กการ์ดบริบทใหม่อย่างมีประสิทธิภาพที่ด้านบนของสแต็กการ์ดที่ไม่ใช่บริบท และการ์ดบริบทนี้คือการ์ดรูทของสแต็กบริบท - แต่หาก
DisplayStyle
คือPEEK
UI จะสร้างส่วนหัวแบบโฉบเฉี่ยวซึ่งปรากฏที่ด้านล่างของแถบด้านข้างของส่วนเสริมแทนโดยวางซ้อนการ์ดปัจจุบัน ส่วนหัว peek จะแสดงชื่อของการ์ดใหม่และมีปุ่มสำหรับควบคุมให้ผู้ใช้ตัดสินใจว่าจะดูการ์ดใหม่หรือไม่ หากผู้ใช้คลิกปุ่มดู การ์ดดังกล่าวจะแทนที่การ์ดปัจจุบัน (ตามที่อธิบายไว้ข้างต้นด้วยREPLACE
)
คุณสามารถสร้างการ์ดบริบทเพิ่มเติมและดันการ์ดเข้าไปในกลุ่มการ์ด ("การ์ดแบบพุช" สีเหลืองในแผนภาพ) การอัปเดตการกองซ้อนการ์ดจะเปลี่ยน UI ของส่วนเสริมให้แสดงการ์ดบนสุด หากผู้ใช้ออกจากบริบท ระบบจะนำการ์ดบริบทในชุดรายการออก และอัปเดตการแสดงผลเป็นการ์ดหรือหน้าแรกที่ไม่ใช่บริบทด้านบนสุด
หากผู้ใช้เข้าสู่บริบทที่ส่วนเสริมของคุณไม่ได้กำหนดทริกเกอร์ตามบริบท จะไม่มีการสร้างการ์ดใหม่ และการ์ดปัจจุบันจะยังแสดงอยู่
การดำเนินการ Navigation
ที่อธิบายไว้ด้านล่างจะดำเนินการกับการ์ดจากบริบทเดียวกันเท่านั้น เช่น popToRoot()
จากภายในการ์ดบริบทจะแสดงเฉพาะการ์ดบริบทอื่นๆ ทั้งหมดเท่านั้น และจะไม่ส่งผลต่อการ์ดในหน้าแรก
ในทางตรงกันข้าม ปุ่ม
จะพร้อมให้ผู้ใช้เลื่อนดูจากการ์ดบริบทไปยังการ์ดที่ไม่ใช่บริบทได้เสมอวิธีการนำทาง
คุณสามารถสร้างการเปลี่ยนระหว่างการ์ดได้โดยการเพิ่มหรือนำการ์ดออกจากชุดการ์ด คลาส Navigation
มีฟังก์ชันสำหรับพุชและป๊อปการ์ดจากสแต็ก หากต้องการสร้าง
การไปยังส่วนต่างๆ ของการ์ดที่มีประสิทธิภาพ คุณต้องกำหนดค่า
วิดเจ็ตเพื่อใช้
การดำเนินการ
สำหรับการไปยังส่วนต่างๆ คุณสามารถพุชหรือป๊อปการ์ดหลายใบพร้อมกัน แต่จะลบการ์ดหน้าแรกแรกที่พุชเข้าไปในสแต็กตอนเริ่มส่วนเสริมไม่ได้
หากต้องการไปยังการ์ดใหม่ตามการโต้ตอบของผู้ใช้กับวิดเจ็ต ให้ทำตามขั้นตอนต่อไปนี้
- สร้างออบเจ็กต์
Action
และเชื่อมโยงกับฟังก์ชันเรียกกลับที่คุณกำหนด - เรียกใช้ฟังก์ชันเครื่องจัดการวิดเจ็ตที่เหมาะสมของวิดเจ็ตเพื่อตั้งค่า
Action
ในวิดเจ็ตนั้น - ใช้ฟังก์ชันเรียกกลับที่ดำเนินการนำทาง ฟังก์ชันนี้จะได้รับออบเจ็กต์เหตุการณ์การกระทำเป็นอาร์กิวเมนต์ และต้องทำดังต่อไปนี้
- สร้างออบเจ็กต์
Navigation
เพื่อกำหนดการเปลี่ยนแปลงการ์ด ออบเจ็กต์Navigation
รายการเดียวอาจมีขั้นตอนการนำทางหลายขั้นตอน ซึ่งจะดำเนินการตามลำดับการเพิ่มในออบเจ็กต์ - สร้างออบเจ็กต์
ActionResponse
โดยใช้คลาสActionResponseBuilder
และออบเจ็กต์Navigation
- ส่งคืน
ActionResponse
เวอร์ชันที่สร้าง
- สร้างออบเจ็กต์
เมื่อสร้างตัวควบคุมการไปยังส่วนต่างๆ คุณจะใช้ฟังก์ชันของออบเจ็กต์ Navigation
ต่อไปนี้
การทำงาน | คำอธิบาย |
---|---|
Navigation.pushCard(Card) |
พุชการ์ดไปยังสแต็กปัจจุบัน คุณจำเป็นต้องสร้างบัตรให้เสร็จสมบูรณ์ก่อน |
Navigation.popCard() |
นำการ์ด 1 ใบออกจากด้านบนสุดของกลุ่มการ์ด ซึ่งเท่ากับการคลิกลูกศรย้อนกลับในแถวส่วนหัวของส่วนเสริม การดำเนินการนี้จะไม่นำการ์ดรูทออก |
Navigation.popToRoot() |
นำการ์ดทั้งหมดออกจากสแต็ก ยกเว้นการ์ดรูท ซึ่งหลักๆ แล้วจะรีเซ็ตสแต็กการ์ดนั้น |
Navigation.popToNamedCard(String) |
แสดงการ์ดจากสแต็กจนกว่าจะถึงการ์ดที่มีชื่อนั้นๆ หรือการ์ดรูทของสแต็ก คุณสามารถกำหนดชื่อให้กับการ์ดโดยใช้ฟังก์ชัน CardBuilder.setName(String) |
Navigation.updateCard(Card) |
เปลี่ยนบัตรปัจจุบันแทนการ์ดปัจจุบันแทนบัตรปัจจุบัน โดยรีเฟรชบัตรดังกล่าวใน UI |
แนวทางปฏิบัติแนะนำในการไปยังส่วนต่างๆ
หากการโต้ตอบหรือเหตุการณ์ของผู้ใช้ควรส่งผลให้การ์ดแสดงผลอีกครั้งในบริบทเดียวกัน ให้ใช้เมธอด Navigation.pushCard()
, Navigation.popCard()
และ Navigation.updateCard()
เพื่อแทนที่การ์ดที่มีอยู่ หากการโต้ตอบหรือเหตุการณ์ของผู้ใช้ควรส่งผลให้การ์ดแสดงผลอีกครั้งในบริบทอื่น ให้ใช้ ActionResponseBuilder.setStateChanged()
เพื่อบังคับให้มีการเรียกใช้ส่วนเสริมอีกครั้งในบริบทดังกล่าว
ต่อไปนี้เป็นตัวอย่างการนำทาง
- หากการโต้ตอบหรือเหตุการณ์เปลี่ยนสถานะของการ์ดปัจจุบัน (เช่น การเพิ่มงานลงในรายการงาน) ให้ใช้
updateCard()
- หากการโต้ตอบหรือกิจกรรมให้รายละเอียดเพิ่มเติมหรือแจ้งให้ผู้ใช้ดำเนินการเพิ่มเติม (เช่น คลิกที่ชื่อรายการเพื่อดูรายละเอียดเพิ่มเติม หรือกดปุ่มเพื่อสร้างกิจกรรมในปฏิทินใหม่) ให้ใช้
pushCard()
เพื่อแสดงหน้าใหม่และอนุญาตให้ผู้ใช้ออกจากหน้าใหม่โดยใช้ปุ่มย้อนกลับ - หากการโต้ตอบหรือเหตุการณ์อัปเดตสถานะในการ์ดก่อนหน้า (เช่น อัปเดตชื่อรายการจากมุมมองรายละเอียด) ให้ใช้
popCard()
,popCard()
,pushCard(previous)
และpushCard(current)
เพื่ออัปเดตการ์ดก่อนหน้าและการ์ดปัจจุบัน
กำลังรีเฟรชการ์ด
ส่วนเสริมของ Google Workspace ช่วยให้ผู้ใช้รีเฟรชการ์ดได้โดยเรียกใช้ฟังก์ชันทริกเกอร์ Apps Script อีกครั้งที่ลงทะเบียนไว้ในไฟล์ Manifest ผู้ใช้จะเรียกการรีเฟรชนี้ผ่านรายการในเมนูส่วนเสริม ดังนี้
ระบบจะเพิ่มการดำเนินการนี้ลงในการ์ดที่ฟังก์ชันทริกเกอร์ homepageTrigger
หรือ contextualTrigger
สร้างขึ้นโดยอัตโนมัติตามที่ระบุไว้ในไฟล์ Manifest ของส่วนเสริม ("ราก" ของสแต็กการ์ดตามบริบทและที่ไม่ใช่บริบท)
การส่งคืนบัตรหลายใบ
ฟังก์ชันทริกเกอร์หน้าแรกหรือบริบทมีไว้เพื่อสร้างและแสดงผลออบเจ็กต์ Card
รายการเดียวหรืออาร์เรย์ของออบเจ็กต์ Card
ที่ UI ของแอปพลิเคชันแสดง
หากมีการ์ดเพียงใบเดียว ระบบจะเพิ่มการ์ดนั้นลงในสแต็กที่ไม่ใช่บริบทหรือบริบทเมื่อการ์ดรูทและ UI ของแอปพลิเคชันโฮสต์จะแสดงการ์ดนั้น
หากอาร์เรย์ที่แสดงผลมีออบเจ็กต์ Card
ที่สร้างขึ้นมากกว่า 1 รายการ แอปพลิเคชันโฮสต์จะแสดงการ์ดใหม่แทน ซึ่งประกอบด้วยรายการส่วนหัวของการ์ดแต่ละใบ เมื่อผู้ใช้คลิกส่วนหัวเหล่านั้น 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();
}