Hầu hết các tiện ích bổ sung dựa trên thẻ đều được tạo bằng nhiều thẻ đại diện cho nhiều "trang" của giao diện tiện ích bổ sung. Để mang lại trải nghiệm hiệu quả cho người dùng, bạn nên sử dụng tính năng điều hướng đơn giản và tự nhiên giữa các thẻ trong tiện ích bổ sung.
Ban đầu, trong các tiện ích bổ sung của Gmail, quá trình chuyển đổi giữa các thẻ khác nhau của giao diện người dùng được xử lý bằng cách đẩy và bật thẻ vào và ra khỏi một ngăn xếp thẻ duy nhất, với thẻ trên cùng của ngăn xếp do Gmail hiển thị.
Tiện ích bổ sung của Google Workspace ra mắt
trang chủ và
thẻ không theo ngữ cảnh. Để phù hợp với các thẻ theo ngữ cảnh và không theo ngữ cảnh,
tiện ích bổ sung của Google Workspace có một ngăn xếp thẻ nội bộ
cho mỗi thẻ. Khi một tiện ích bổ sung được mở trong máy chủ lưu trữ, homepageTrigger
tương ứng sẽ kích hoạt để tạo thẻ trang chủ đầu tiên trên ngăn xếp (thẻ "trang chủ" màu xanh dương đậm trong sơ đồ bên dưới).
Nếu không xác định homepageTrigger
, hệ thống sẽ tạo, hiển thị và đẩy một thẻ mặc định vào ngăn xếp không theo ngữ cảnh. Thẻ đầu tiên này là thẻ gốc.
Tiện ích bổ sung của bạn có thể tạo thêm các thẻ không theo ngữ cảnh và đẩy các thẻ đó vào ngăn xếp ("thẻ được đẩy" màu xanh dương trong sơ đồ) khi người dùng di chuyển qua tiện ích bổ sung của bạn. Giao diện người dùng của tiện ích bổ sung hiển thị thẻ trên cùng trong ngăn xếp, vì vậy, việc đẩy thẻ mới vào ngăn xếp sẽ thay đổi màn hình và việc đẩy thẻ ra khỏi ngăn xếp sẽ trả về màn hình cho các thẻ trước đó.
Nếu tiện ích bổ sung của bạn có một trình kích hoạt theo bối cảnh đã xác định, thì trình kích hoạt sẽ kích hoạt khi người dùng nhập vào bối cảnh đó. Hàm kích hoạt tạo thẻ theo bối cảnh, nhưng màn hình giao diện người dùng được cập nhật dựa trên DisplayStyle
của thẻ mới:
- Nếu
DisplayStyle
làREPLACE
(mặc định), thì thẻ theo ngữ cảnh (thẻ "theo ngữ cảnh" màu cam đậm trong sơ đồ) sẽ thay thế thẻ hiện đang hiển thị. Thao tác này sẽ bắt đầu một ngăn xếp thẻ theo ngữ cảnh mới một cách hiệu quả ở đầu ngăn xếp thẻ không theo ngữ cảnh và thẻ theo ngữ cảnh này là thẻ gốc của ngăn xếp theo ngữ cảnh. - Nếu
DisplayStyle
làPEEK
, giao diện người dùng sẽ tạo một tiêu đề xem trước xuất hiện ở cuối thanh bên tiện ích bổ sung, phủ lên thẻ hiện tại. Tiêu đề xem trước cho biết tiêu đề của thẻ mới và cung cấp các nút điều khiển cho người dùng để họ quyết định xem có xem thẻ mới hay không. Nếu người dùng nhấp vào nút Xem, thẻ này sẽ thay thế thẻ hiện tại (như mô tả ở trên bằngREPLACE
).
Bạn có thể tạo thêm các thẻ theo ngữ cảnh và đẩy các thẻ đó vào ngăn xếp ("thẻ được đẩy" màu vàng trong sơ đồ). Việc cập nhật ngăn xếp thẻ sẽ thay đổi giao diện người dùng của tiện ích bổ sung để hiển thị thẻ trên cùng. Nếu người dùng rời khỏi một ngữ cảnh, các thẻ theo ngữ cảnh trên ngăn xếp sẽ bị xoá và màn hình sẽ cập nhật thành thẻ không theo ngữ cảnh hoặc trang chủ ở trên cùng.
Nếu người dùng nhập một ngữ cảnh mà tiện ích bổ sung của bạn không xác định điều kiện kích hoạt theo ngữ cảnh, thì hệ thống sẽ không tạo thẻ mới và thẻ hiện tại sẽ vẫn hiển thị.
Các thao tác Navigation
được mô tả bên dưới chỉ hoạt động trên các thẻ thuộc cùng một ngữ cảnh; ví dụ: popToRoot()
trong thẻ theo ngữ cảnh chỉ bật lên tất cả các thẻ theo ngữ cảnh khác và sẽ không ảnh hưởng đến thẻ trang chủ.
Ngược lại, nút
luôn có sẵn để người dùng di chuyển từ thẻ theo ngữ cảnh sang thẻ không theo ngữ cảnh.Phương thức điều hướng
Bạn có thể tạo hiệu ứng chuyển đổi giữa các thẻ bằng cách thêm hoặc xoá thẻ khỏi ngăn xếp thẻ. Lớp Navigation
cung cấp các hàm để đẩy và bật thẻ từ ngăn xếp. Để tạo tính năng điều hướng thẻ hiệu quả, bạn định cấu hình tiện ích để sử dụng thao tác điều hướng. Bạn có thể đẩy hoặc bật lên nhiều thẻ cùng một lúc, nhưng không thể xoá thẻ trang chủ ban đầu được đẩy vào ngăn xếp đầu tiên khi tiện ích bổ sung bắt đầu.
Để chuyển đến một thẻ mới khi người dùng tương tác với một tiện ích, hãy làm theo các bước sau:
- Tạo một đối tượng
Action
và liên kết đối tượng đó với một hàm gọi lại mà bạn xác định. - Gọi hàm xử lý tiện ích thích hợp của tiện ích để đặt
Action
trên tiện ích đó. - Triển khai hàm gọi lại để điều hướng. Hàm này được cung cấp một đối tượng sự kiện hành động làm đối số và phải thực hiện những việc sau:
- Tạo đối tượng
Navigation
để xác định thay đổi thẻ. Một đối tượngNavigation
có thể chứa nhiều bước điều hướng, được thực hiện theo thứ tự thêm vào đối tượng. - Tạo đối tượng
ActionResponse
bằng cách sử dụng lớpActionResponseBuilder
và đối tượngNavigation
. - Trả về
ActionResponse
đã tạo.
- Tạo đối tượng
Khi xây dựng các nút điều khiển điều hướng, bạn sẽ sử dụng các hàm đối tượng Navigation
sau:
Chức năng | Mô tả |
---|---|
Navigation.pushCard(Card) |
Đẩy một thẻ vào ngăn xếp hiện tại. Trước tiên, bạn cần tạo hoàn toàn thẻ. |
Navigation.popCard() |
Xoá một thẻ khỏi đầu ngăn xếp. Tương đương với việc nhấp vào mũi tên quay lại trong hàng tiêu đề của tiện ích bổ sung. Thao tác này không xoá thẻ gốc. |
Navigation.popToRoot() |
Xoá tất cả các thẻ khỏi ngăn xếp, ngoại trừ thẻ gốc. Về cơ bản, đặt lại ngăn xếp thẻ đó. |
Navigation.popToNamedCard(String) |
Đẩy các thẻ ra khỏi ngăn xếp cho đến khi gặp một thẻ có tên đã cho hoặc thẻ gốc của ngăn xếp. Bạn có thể gán tên cho thẻ bằng hàm CardBuilder.setName(String) . |
Navigation.updateCard(Card) |
Thay thế thẻ hiện tại tại chỗ, làm mới màn hình hiển thị của thẻ đó trong giao diện người dùng. |
Phương pháp hay nhất về điều hướng
Nếu một sự kiện hoặc lượt tương tác của người dùng dẫn đến việc kết xuất lại thẻ trong cùng một ngữ cảnh, hãy sử dụng các phương thức Navigation.pushCard()
, Navigation.popCard()
và Navigation.updateCard()
để thay thế các thẻ hiện có. Nếu một sự kiện hoặc lượt tương tác của người dùng dẫn đến việc kết xuất lại thẻ trong một ngữ cảnh khác, hãy sử dụng ActionResponseBuilder.setStateChanged()
để buộc thực thi lại tiện ích bổ sung trong các ngữ cảnh đó.
Sau đây là ví dụ về điều hướng:
- Nếu một lượt tương tác hoặc sự kiện thay đổi trạng thái của thẻ hiện tại (ví dụ: thêm một việc cần làm vào danh sách việc cần làm), hãy sử dụng
updateCard()
. - Nếu một lượt tương tác hoặc sự kiện cung cấp thêm thông tin chi tiết hoặc nhắc người dùng thực hiện hành động khác (ví dụ: nhấp vào tiêu đề của một mục để xem thêm thông tin chi tiết hoặc nhấn nút để tạo một sự kiện Lịch mới), hãy sử dụng
pushCard()
để hiển thị trang mới trong khi cho phép người dùng thoát khỏi trang mới bằng nút quay lại. - Nếu một lượt tương tác hoặc sự kiện cập nhật trạng thái trong thẻ trước đó (ví dụ: cập nhật tiêu đề của một mục bằng chế độ xem chi tiết), hãy sử dụng các mã như
popCard()
,popCard()
,pushCard(previous)
vàpushCard(current)
để cập nhật thẻ trước đó và thẻ hiện tại.
Làm mới thẻ
Tiện ích bổ sung của Google Workspace cho phép người dùng làm mới thẻ bằng cách chạy lại hàm kích hoạt Apps Script đã đăng ký trong tệp kê khai. Người dùng kích hoạt quá trình làm mới này thông qua một mục trình đơn tiện ích bổ sung:
Thao tác này được tự động thêm vào các thẻ do các hàm kích hoạt homepageTrigger
hoặc contextualTrigger
tạo ra, như được chỉ định trong tệp kê khai của tiện ích bổ sung ('gốc' của ngăn xếp thẻ theo bối cảnh và không theo bối cảnh).
Trả về nhiều thẻ
Hàm kích hoạt theo bối cảnh hoặc trang chủ được dùng để tạo và trả về một đối tượng Card
hoặc một mảng các đối tượng Card
mà giao diện người dùng của ứng dụng hiển thị.
Nếu chỉ có một thẻ, thẻ đó sẽ được thêm vào ngăn xếp không theo ngữ cảnh hoặc theo ngữ cảnh dưới dạng thẻ gốc và giao diện người dùng của ứng dụng lưu trữ sẽ hiển thị thẻ đó.
Nếu mảng được trả về bao gồm nhiều đối tượng Card
tích hợp, thì ứng dụng lưu trữ sẽ hiển thị một thẻ mới, chứa danh sách tiêu đề của từng thẻ. Khi người dùng nhấp vào bất kỳ tiêu đề nào trong số đó, giao diện người dùng sẽ hiển thị thẻ tương ứng.
Khi người dùng chọn một thẻ trong danh sách, thẻ đó sẽ được đẩy vào ngăn xếp hiện tại và ứng dụng lưu trữ sẽ hiển thị thẻ đó. Nút
sẽ đưa người dùng trở lại danh sách tiêu đề thẻ.Cách sắp xếp thẻ "phẳng" này có thể hoạt động tốt nếu tiện ích bổ sung của bạn không cần bất kỳ chuyển đổi nào giữa các thẻ mà bạn tạo. Tuy nhiên, trong hầu hết các trường hợp, bạn nên xác định trực tiếp các hiệu ứng chuyển đổi thẻ, đồng thời yêu cầu trang chủ và các hàm kích hoạt theo ngữ cảnh trả về một đối tượng thẻ duy nhất.
Ví dụ:
Dưới đây là ví dụ minh hoạ cách tạo một số thẻ có các nút điều hướng để chuyển đổi giữa các thẻ đó. Bạn có thể thêm các thẻ này vào ngăn xếp theo ngữ cảnh hoặc không theo ngữ cảnh bằng cách đẩy thẻ do createNavigationCard()
trả về trong hoặc ngoài một ngữ cảnh cụ thể.
/**
* 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();
}