
一、應用概述底部導航Bottom Navigation是一個模擬主流 App 底部 Tab 切換的演示應用。四個標簽頁首頁、發(fā)現(xiàn)、消息、我的各自關聯(lián)不同的頁面內(nèi)容點擊標簽平滑切換內(nèi)容區(qū)域。底部導航欄是移動應用中最常見的導航模式iOS 的 UITabBar 和 Android 的 BottomNavigationView 都采用類似設計。在 HarmonyOS 中底部導航的實現(xiàn)沒有使用專門的 TabBar 組件雖然有Tabs組件而是通過RowForEach手動構建導航欄配合State狀態(tài)驅(qū)動內(nèi)容切換。這種「造輪子」的方式反而讓我們更深入地理解了狀態(tài)驅(qū)動的本質(zhì)。二、技術架構2.1 應用結構┌─────────────────────────────────────┐ │ ? 返回 底部導航 │ ├─────────────────────────────────────┤ │ │ │ 大圖標 │ │ │ │ 歡迎來到底部導航演示 │ │ 這是首頁的內(nèi)容區(qū)域 │ │ 可以放置各種信息和功能卡片 │ │ │ │ │ ├─────────────────────────────────────┤ │ │ ← 底部導航欄 │ 首頁 發(fā)現(xiàn) 消息 我的 │ └─────────────────────────────────────┘2.2 數(shù)據(jù)模型interface TabItem { title: string; // 標簽名稱 icon: string; // emoji 圖標 content: string; // 頁面內(nèi)容含換行符 color: string; // 標簽主題色選中時使用 }2.3 狀態(tài)變量變量類型用途currentTabnumber當前選中的標簽索引0-3tabsTabItem[]4 個標簽的配置數(shù)據(jù)三、核心代碼深度解析3.1 狀態(tài)驅(qū)動的 Tab 切換State currentTab: number 0;僅用一個number類型的State變量就驅(qū)動了整個頁面的切換。這個數(shù)字既是底部導航欄的選中索引也是內(nèi)容區(qū)域的顯示索引。內(nèi)容區(qū)域Column() { Text(this.tabs[this.currentTab].icon).fontSize(64).margin({ bottom: 16 }) Text(this.tabs[this.currentTab].content) .fontSize(16).fontColor(#555).lineHeight(28).textAlign(TextAlign.Center) } .layoutWeight(1).justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center)通過this.currentTab索引tabs數(shù)組動態(tài)獲取當前標簽的 icon、content 和 color。這是 ArkUI 中「數(shù)據(jù)驅(qū)動 UI」最直接的體現(xiàn)——只需更新currentTab所有相關 UI 自動刷新。3.2 底部導航欄Row() { ForEach(this.tabs, (tab: TabItem, idx: number) { Column() { Text(tab.icon).fontSize(22) .opacity(this.currentTab idx ? 1 : 0.5) Text(tab.title).fontSize(11) .fontColor(this.currentTab idx ? tab.color : #999) .fontWeight(this.currentTab idx ? FontWeight.Medium : FontWeight.Regular) } .layoutWeight(1) .padding({ top: 6, bottom: 6 }) .onClick(() { this.currentTab idx }) }) } .width(100%).height(64) .backgroundColor(#fff) .borderRadius({ topLeft: 16, topRight: 16 }) .shadow({ radius: 8, color: #20000000, offsetY: -2 })導航欄的樣式設計屬性值說明高度64標準導航欄高度符合人體工學背景色#fff純白背景圓角{ topLeft: 16, topRight: 16 }僅頂部圓角與底部邊緣平滑過渡陰影offsetY: -2向上偏移產(chǎn)生「浮在內(nèi)容之上」的效果選中/未選中狀態(tài)對比樣式屬性未選中選中圖標透明度0.51.0文字顏色#999灰色tab.color主題色文字字重RegularMedium這種「透明度顏色字重」的三重區(qū)分確保了選中狀態(tài)的清晰可辨同時保持了整體視覺的協(xié)調(diào)性。3.3 圓角與陰影的巧妙運用.borderRadius({ topLeft: 16, topRight: 16 }) .shadow({ radius: 8, color: #20000000, offsetY: -2 })borderRadius 對象語法ArkUI 支持為四個角分別設置圓角半徑格式為{ topLeft, topRight, bottomLeft, bottomRight }。這里只設定了頂部兩個角的圓角底部緊貼屏幕邊緣形成懸浮導航欄的效果。陰影向上偏移offsetY: -2表示陰影向上偏移 2vp配合radius: 8較大的模糊半徑產(chǎn)生導航欄「浮在內(nèi)容上方」的視覺效果。這與 Material Design 的 Bottom App Bar 設計語言一致。四、HarmonyOS 特色功能深度解析4.1 layoutWeight 彈性布局.layoutWeight(1)每個 Tab 項都設置layoutWeight(1)在Row容器中等分寬度。無論屏幕寬度是 360vp 還是 428vp四個 Tab 自動平分底部空間。layoutWeight 的計算規(guī)則先分配所有未設置layoutWeight的組件的固定寬度剩余空間按layoutWeight值比例分配給設置了該屬性的組件如果所有子組件都設置了layoutWeight(1)則等分總寬度4.2 ForEach 的索引參數(shù)ForEach(this.tabs, (tab: TabItem, idx: number) { // idx 就是當前項的索引 .onClick(() { this.currentTab idx }) })ForEach的回調(diào)函數(shù)可以接收兩個參數(shù)第一個參數(shù)數(shù)組中的元素值第二個參數(shù)元素在數(shù)組中的索引從 0 開始使用索引參數(shù)可以避免為每個 Tab 手動綁定onClick事件這是 ForEach 簡化代碼的重要特性。4.3 Text 組件的多行內(nèi)容content: 歡迎來到底部導航演示\n\n這是首頁的內(nèi)容區(qū)域\n可以放置各種信息和功能卡片在Text組件中使用\n換行符可以實現(xiàn)多行文本顯示配合lineHeight屬性控制行間距。這是最簡單的內(nèi)容換行方式不需要使用多個Text組件堆疊。五、UI/UX 設計分析5.1 四標簽導航四個標簽覆蓋了主流 App 的標準導航結構標簽圖標主題色典型用途首頁#0077FF藍色內(nèi)容信息流發(fā)現(xiàn)#4CAF50綠色搜索/探索消息#FF9800橙色通知/聊天我的#9C27B0紫色個人中心色彩心理學四種主題色分別代表不同的功能屬性——藍色專業(yè)、綠色自然、橙色活躍、紫色創(chuàng)意。5.2 沉浸式導航欄設計底部導航欄的設計借鑒了現(xiàn)代移動操作系統(tǒng)的設計語言懸浮效果白色背景 頂部圓角 向上陰影模擬物理懸浮觸控熱區(qū)padding({ top: 6, bottom: 6 })確保每個 Tab 的點擊區(qū)域足夠大至少 44vp 的觸控高度視覺權重圖標 22px 文字 11px圖標視覺權重更大易于識別5.3 內(nèi)容區(qū)域設計內(nèi)容區(qū)域居中顯示大圖標和歡迎文字圖標fontSize(64)大尺寸圖標形成視覺焦點文字lineHeight(28)舒適的閱讀行距textAlign(TextAlign.Center)居中排列六、最佳實踐與優(yōu)化建議6.1 當前代碼亮點極簡狀態(tài)管理僅用currentTab一個變量完成全部切換邏輯數(shù)據(jù)驅(qū)動 UI所有顯示內(nèi)容來自tabs數(shù)組新增標簽只需修改數(shù)據(jù)導航欄懸浮設計圓角 陰影營造沉浸視覺體驗Tab 等分布局layoutWeight(1)實現(xiàn)自適應寬度6.2 可優(yōu)化方向// 優(yōu)化建議 1頁面切換動畫 // 使用 transition 添加頁面切換動畫 Column() .transition({ type: TransitionType.Insert, translate: { x: 100 } }) .transition({ type: TransitionType.Delete, translate: { x: -100 } }) // 優(yōu)化建議 2使用 Tabs 組件替代手動構建 // HarmonyOS 提供了 Tabs TabContent 原生組件 Tabs() { TabContent() { /* 首頁內(nèi)容 */ }.tabBar( 首頁) TabContent() { /* 發(fā)現(xiàn)內(nèi)容 */ }.tabBar( 發(fā)現(xiàn)) TabContent() { /* 消息內(nèi)容 */ }.tabBar( 消息) TabContent() { /* 我的內(nèi)容 */ }.tabBar( 我的) } .barPosition(BarPosition.End) // 導航欄在底部 // 優(yōu)化建議 3角標通知 // 在 Tab 圖標上顯示未讀數(shù)量 Stack() { Text(tab.icon).fontSize(22) if (unreadCount 0) { Text(unreadCount 99 ? 99 : unreadCount.toString()) .fontSize(10).fontColor(#fff) .backgroundColor(#F44336).borderRadius(8) .padding({ left: 4, right: 4 }).height(16) .align(Alignment.TopEnd) } } // 優(yōu)化建議 4頁面緩存 // 使用 State 保存每個 Tab 的滾動位置 State scrollPositions: number[] [0, 0, 0, 0]; // 優(yōu)化建議 5導航欄隱藏/顯示 // 根據(jù)內(nèi)容滾動方向自動隱藏/顯示導航欄 State navBarVisible: boolean true;6.3 性能優(yōu)化Tab 數(shù)量控制底部導航建議不超過 5 個 TabMaterial Design 規(guī)范超過時需使用「更多」折疊或滾動模式內(nèi)容懶加載當前實現(xiàn)中 4 個 Tab 的內(nèi)容同時存在通過currentTab控制顯示對于內(nèi)容較重的頁面應使用懶加載圖標性能使用 emoji 而非圖片圖標減少資源加載開銷七、總結與擴展底部導航應用展示了 ArkUI 中實現(xiàn) Tab 導航的核心模式知識點應用位置重要程度State 狀態(tài)驅(qū)動currentTab 切換★★★★★layoutWeight 彈性布局Tab 等分★★★★★ForEach 索引參數(shù)onClick 事件綁定★★★★☆borderRadius 對象語法導航欄圓角★★★☆☆shadow 陰影懸浮效果★★★☆☆擴展思路與 Tabs 組件對比學習 HarmonyOS 原生Tabs組件的 API了解手動構建與原生組件的權衡中間大按鈕部分 App 在底部導航欄中間放置大按鈕如發(fā)帖按鈕可通過Stack布局實現(xiàn)導航欄顏色跟隨根據(jù)所在 Tab 的主題色改變導航欄顏色返回攔截配合onBackPress實現(xiàn)雙擊退出或確認提示跨頁面狀態(tài)保持使用AppStorage在頁面切換時保持 Tab 狀態(tài)手勢切換添加左右滑動手勢SwipeGesture切換 Tab底部導航是現(xiàn)代移動應用的標準導航模式。通過這個案例你不僅學會了如何構建底部導航欄更理解了狀態(tài)驅(qū)動的本質(zhì)——一個數(shù)字的變化驅(qū)動整個頁面的重新渲染。這就是聲明式 UI 的核心思想UI 是狀態(tài)的函數(shù)。