HarmonyOS Navigation Deep Dive: Dialog Routing with NavDestination Dialog Mode
This article explains how to implement dialog routing in HarmonyOS using the Navigation component's Dialog mode, contrasting Standard and Dialog NavDestination modes, and provides a complete shopping cart example with ArkTS code demonstrating persistent, non-blocking dialogs with transition effects.
In real-world business scenarios, developers often need a lightweight container to display temporary information or request user actions without interrupting the main task flow. The Dialog component serves this purpose well. Implementing dialogs through HarmonyOS Navigation offers additional benefits: dialogs become persistent and survive page navigation, provide finer layer control, and can leverage Navigation's built-in transition animations for a smoother user experience.
NavDestination Modes: Standard vs Dialog
The Navigation component's child pages ( NavDestination) support two modes configured via the mode property:
Standard (default): Standard pages have a white background. In the page stack, only the topmost Standard page is visible; others are hidden and cannot update their state. This mode suits regular content pages.
Dialog : Dialog pages have a transparent background by default. They can appear above Standard pages, multiple Dialog pages can be shown simultaneously, and they do not block the underlying Standard page's rendering or interaction. This mode is designed for dialog-style presentations.
The following diagram illustrates the layering relationship between Standard and Dialog pages:
Shopping Cart Dialog Example
The article demonstrates a shopping app where the cart is implemented as a Dialog-mode NavDestination. The example consists of three pages:
Index page – Entry point that initializes a NavPathStack and immediately pushes the Product page.
Product page – A Standard-mode NavDestination with a toolbar button that pushes the ShoppingCart route.
ShoppingCart page – A Dialog-mode NavDestination that displays a list of 50 mock products. Tapping the dimmed background area calls stack.pop() to dismiss the dialog.
Complete ArkTS Code
// Navigation Home src/main/ets/pages/Index.ets
@Entry
@Component
struct Index {
private stack: NavPathStack = new NavPathStack();
aboutToAppear(): void {
// For demonstration, push a product page initially
this.stack.pushPath({name: 'Product'})
}
build() {
Navigation(this.stack) {
}
.hideNavBar(true)
.height('100%')
.width('100%')
}
}
// Product Page src/main/ets/pages/ProductPage.ets
import { SymbolGlyphModifier } from "@kit.ArkUI";
@Component
struct ProductPage {
private stack: NavPathStack | undefined = undefined;
build() {
NavDestination() {
}.title('Product Page')
.toolbarConfiguration([
{
value: 'Shopping Cart',
symbolIcon: new SymbolGlyphModifier($r('sys.symbol.cart')),
action: () => {
this.stack?.pushPath({name: "ShoppingCart"})
}
}
])
.mode(NavDestinationMode.STANDARD)
.onReady((ctx: NavDestinationContext) => {
this.stack = ctx.pathStack;
})
}
}
@Builder
export function ProductPageBuilder() {
ProductPage()
}
// Shopping Cart Page src/main/ets/pages/ShoppingCartPage.ets
class ProductInfo {
// Product name
name: string;
// Product count
count: number;
constructor(name: string, count: number) {
this.name = name;
this.count = count;
}
}
@Component
struct ShoppingCartPage {
private stack: NavPathStack | undefined = undefined;
private products: Array<ProductInfo> = new Array<ProductInfo>();
aboutToAppear(): void {
// Assume cart already has some products
for (let i = 0; i < 50; i++) {
this.products.push(new ProductInfo(`Product${i}`, i + 1));
}
}
build() {
NavDestination() {
Column() {
Blank().onClick(() => {
// Clicking blank area of Dialog page returns to product page
this.stack?.pop()
}).width('100%').layoutWeight(1)
Column() {
// Shopping cart list
Text('Shopping Cart').fontSize(20).margin(8)
List() {
ForEach(this.products, (info: ProductInfo, index: number) => {
ListItem() {
Row() {
Text(`${info.name}`).margin(12).fontSize(18).fontColor(Color.Black)
Text(`Quantity: ${info.count}`).fontSize(13).margin({right: 18})
}.margin({bottom: 15 }).backgroundColor('#fff3dab9').width('100%').justifyContent(FlexAlign.SpaceBetween)
.borderRadius(15).height(80)
}.width('100%')
}, (info: ProductInfo, index: number) => {
return info.name;
})
}
}.width('100%').layoutWeight(2).backgroundColor('#ffdaf3b5').border({})
}.width('100%').height('100%')//.backgroundColor('#2df8e8e8')
}
.hideTitleBar(true)
.hideToolBar(true)
// Shopping cart page is Dialog type
.mode(NavDestinationMode.DIALOG)
.onReady((ctx: NavDestinationContext) => {
this.stack = ctx.pathStack;
})
}
}
@Builder
export function ShoppingCartPageBuilder() {
ShoppingCartPage()
}The screenshot below shows the running effect: the shopping cart dialog overlays the product page with a dimmed background, and the product list is scrollable within the dialog.
For more detailed solutions and code examples, refer to the original article "ArkUI Navigation Component Comprehensive Analysis: From Basic Navigation to Advanced Routing Practice".
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
HarmonyOS Developer Technology
HarmonyOS developers provide key technology analysis, version updates, Codelabs practice, and event information for HarmonyOS. Welcome developers to join the HarmonyOS ecosystem and create infinite possibilities together!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
