
引言在移動應用的導航體系中抽屜式菜單Drawer Navigation是最經典的導航模式之一。從最早的 Android 原生 Navigation Drawer到 Material Design 中規范的 Navigation Rail再到各平臺對側滑手勢的原生支持抽屜導航以其「隱藏式面板 內容覆蓋」的獨特交互成為了承載多級菜單、用戶中心、功能入口等場景的不二之選。HarmonyOS NEXT 提供了SideBarContainer組件以聲明式的方式實現了抽屜導航支持 Overlay覆蓋式和 Inline內聯式兩種展示模式。示例 91 以「我的菜單」為主題實現了一個左側抽屜導航頁面。用戶點擊「打開菜單」按鈕左側菜單欄會從左側滑出覆蓋在主內容區之上菜單項以列表形式排列支持選中高亮點擊菜單項后菜單自動收起主內容區顯示選中狀態并通過promptAction.showToast彈出操作反饋。整個流程涉及SideBarContainer的狀態綁定、菜單項的ForEach渲染、選中態的視覺反饋、以及onChange事件的雙向同步幾乎涵蓋了抽屜導航實現的所有核心要點。這篇文章會嚴格按源碼順序先介紹應用的整體功能與布局結構再拆解SideBarContainer的核心屬性與事件接著逐段解讀.ets源碼中的菜單渲染、選中邏輯、交互反饋然后分析 Overlay 模式與 Inline 模式的區別、showSideBar綁定機制、菜單 UI 的樣式設計思路最后給出運行操作指南、可擴展方向與常見問題調試技巧。讀完后你不僅能看懂這一個側滑菜單頁面還能舉一反三把它應用到用戶中心、功能導航、分類瀏覽等任何需要抽屜導航的場景。1. 應用概述與功能「側滑菜單」是一個面向導航場景的工具型頁面交互路徑清晰點擊打開菜單 → 查看菜單項 → 點擊選中 → 自動收起。頁面自上而下分為三塊區域頂部是返回欄左側「返回」按鈕調用router.back()返回上一頁中間是標題「側滑菜單」中部是SideBarContainer容器左側菜單欄占 40% 寬度深色背景#1f2733右側主內容區占滿剩余空間淺灰背景#f2f3f5底部功能說明卡片列出三條使用提示。1.1 核心功能清單抽屜式菜單展示使用SideBarContainer組件實現左側抽屜菜單支持 Overlay 覆蓋模式。菜單項高亮選中點擊菜單項時選中項文字變藍色#1a6cff、加粗、帶半透明藍色背景未選中項為灰色。自動收起點擊菜單項后側邊欄自動收起給用戶完整的主內容區操作空間。雙向狀態同步通過showSideBar屬性和onChange回調實現菜單展開狀態的雙向綁定。操作反饋點擊菜單項后通過promptAction.showToast彈出提示如「點擊了首頁」。功能說明卡片主內容區底部展示白色圓角卡片列出三條使用提示引導用戶操作。1.2 技術要點一覽整個示例用到的關鍵技術對「抽屜導航」類頁面很有代表性SideBarContainer組件的 Overlay 模式、showSideBar狀態綁定與onChange事件回調、菜單項列表的ForEach渲染與選中態判斷、Text組件的動態樣式綁定顏色、字重、背景色、以及Divider分隔線的使用。把這些要點串起來就構成了一條完整的「狀態驅動 → UI 渲染 → 交互反饋 → 狀態更新」的交互閉環。2. 核心知識點在逐段讀代碼之前先把側滑菜單頁面承載的 ArkTS 核心知識講清楚。2.1 SideBarContainer 組件與 Overlay 模式SideBarContainer是 ArkUI 提供的抽屜容器組件用于實現「側邊欄 主內容區」的布局結構。它支持兩種展示模式SideBarContainerType.Overlay覆蓋模式側邊欄滑出時覆蓋在主內容區之上主內容區不移動。這是最常見的抽屜效果適合移動端。SideBarContainerType.Inline內聯模式側邊欄展開時主內容區被擠壓側邊欄與主內容區并排顯示適合平板或橫屏場景。示例使用的是 Overlay 模式SideBarContainer(SideBarContainerType.Overlay){// 左側菜單欄第一個子組件Column(){...}// 右側主內容區第二個子組件Column(){...}}SideBarContainer接受一個類型參數和兩個子組件第一個子組件是側邊欄內容第二個子組件是主內容區。組件內部會自動處理滑動手勢和動畫過渡。2.2 showSideBar 狀態綁定與 onChange 回調SideBarContainer的展開/收起通過showSideBar屬性控制而onChange回調則在側邊欄狀態變化時觸發SideBarContainer(SideBarContainerType.Overlay){// 子組件...}.showSideBar(this.show).onChange((v:boolean){this.showv;})這里涉及一個雙向綁定的模式正向控制當this.show為true時側邊欄展開為false時收起。反向同步當用戶通過手勢滑動或點擊外部區域使側邊欄收起時onChange回調被觸發參數v會更新this.show的值。這個雙向綁定確保了無論通過哪種方式改變側邊欄狀態this.show都能保持同步。如果只使用showSideBar而不處理onChange那么用戶手動收起菜單后this.show仍然是true下次點擊按鈕時就會出現狀態不一致的問題。2.3 菜單項的動態樣式綁定菜單項的選中態通過動態樣式綁定實現Text(item).fontColor(this.selIdxidx?#1a6cff:#cccccc).fontWeight(this.selIdxidx?FontWeight.Bold:FontWeight.Normal).backgroundColor(this.selIdxidx?rgba(26,108,255,0.18):rgba(0,0,0,0))這是 ArkUI 中條件樣式綁定的標準寫法通過三元運算符根據this.selIdx與當前idx的比較結果動態決定fontColor、fontWeight、backgroundColor三個屬性的值。選中項使用主題藍色#1a6cff、加粗字重、半透明藍色背景未選中項使用淺灰色#cccccc、正常字重、透明背景。這種方式比為選中項單獨創建一個組件更簡潔性能也更好。2.4 ForEach 渲染菜單列表菜單項通過ForEach組件從數組渲染ForEach(this.menus,(item:string,idx:number){Text(item).width(86%).height(52)// ... 其他屬性.onClick((){this.chooseMenu(idx);})},(item:string,idx:number)idx.toString())ForEach的三個參數分別是數據源this.menus數組包含四個菜單項名稱。渲染函數接收每個元素和索引返回對應的 UI 組件。這里返回的是一個帶完整樣式和點擊事件的Text組件。鍵值生成器為每個元素生成唯一的 key用于 ArkUI 的 diff 算法。這里使用idx.toString()作為 key確保每個菜單項有穩定的標識。2.5 promptAction 輕提示promptAction是 ArkUI 提供的輕量級提示 API來自kit.ArkUIimport{promptAction}fromkit.ArkUI;promptAction.showToast({message:點擊了this.menus[idx]});showToast會在屏幕底部彈出一個短消息持續約 2 秒后自動消失。它適用于不需要用戶交互的簡單提示比自定義的AlertDialog更輕量也不需要額外的狀態管理。在側滑菜單這種交互場景中promptAction是最合適的反饋方式。3. 源碼逐段解析現在開始按源碼順序逐段解讀index91.ets從導入聲明到build方法完整展示側滑菜單的實現細節。3.1 導入聲明與組件聲明import{router}fromkit.ArkUI;import{promptAction}fromkit.ArkUI;EntryComponentstruct Index91{源碼開頭導入了兩個 ArkUI 模塊router用于頁面導航調用router.back()返回上一頁promptAction用于輕提示反饋。Entry裝飾器標記該組件為頁面入口Component裝飾器標記該結構體為可復用的 UI 組件。3.2 狀態變量與菜單數據Stateshow:booleanfalse;StateselIdx:number0;privatemenus:string[][首頁,消息,設置,關于];組件聲明了兩個State狀態變量和一個私有數組show控制側邊欄的展開/收起初始為false收起狀態。當用戶點擊「打開菜單」按鈕或菜單項時這個值會被修改。selIdx記錄當前選中的菜單項索引初始為0選中第一項「首頁」。這個值驅動菜單項的高亮樣式和主內容區的選中狀態文本。menus菜單項名稱數組包含四個導航入口。使用private修飾因為它不需要從外部訪問。3.3 chooseMenu 選中處理方法privatechooseMenu(idx:number):void{this.selIdxidx;this.showfalse;promptAction.showToast({message:點擊了this.menus[idx]});}chooseMenu是菜單項點擊的處理函數接收一個參數idx選中的菜單項索引執行三個操作更新selIdx為點擊的索引觸發菜單項的高亮樣式重新渲染。設置show為false自動收起側邊欄。這是側滑菜單的標準交互——選中后自動關閉。通過promptAction.showToast彈出提示告知用戶點擊了哪個菜單項。這三個操作的順序很重要先更新選中態再收起菜單最后彈出提示。如果先收起菜單再更新選中態在菜單收起的動畫過程中用戶可能看到短暫的舊選中狀態。3.4 build 方法整體結構build方法構建了整個頁面的 UI 結構最外層是一個Column包含頂部返回欄和SideBarContainer兩部分build(){Column(){// 頂部返回欄Row(){...}// 側滑菜單容器SideBarContainer(SideBarContainerType.Overlay){...}}.width(100%).height(100%).backgroundColor(#f2f3f5)}最外層Column設置為全屏寬高100%背景色為淺灰色#f2f3f5給整個頁面一個統一的底色。3.5 頂部返回欄Row(){Button(返回).backgroundColor(#1a6cff).fontColor(Color.White).onClick((){router.back();})Text(側滑菜單).fontSize(18).fontWeight(FontWeight.Bold)Blank()}.width(100%).padding({left:12,right:12,top:10,bottom:10})頂部返回欄是一個Row寬度占滿整屏帶內邊距。從左到右依次是藍色「返回」按鈕點擊調用router.back()、居中的標題文字「側滑菜單」、右側的Blank()彈性空白保證標題居中。Blank()是 ArkUI 中一個特殊的彈性空白組件它會占據Row中所有剩余空間。由于Blank()放在標題右側它會把標題推到中間位置實現標題居中的效果。3.6 SideBarContainer 左側菜單欄SideBarContainer是整個頁面的核心它的第一個子組件是左側菜單欄SideBarContainer(SideBarContainerType.Overlay){// 左側菜單欄Column(){Text(我的菜單).fontSize(20).fontColor(Color.White).fontWeight(FontWeight.Bold).margin({top:24,bottom:20})Divider().color(#3a4657).strokeWidth(1).margin({bottom:10})ForEach(this.menus,(item:string,idx:number){Text(item).width(86%).height(52).fontSize(16).fontColor(this.selIdxidx?#1a6cff:#cccccc).fontWeight(this.selIdxidx?FontWeight.Bold:FontWeight.Normal).borderRadius(8).textAlign(TextAlign.Center).backgroundColor(this.selIdxidx?rgba(26,108,255,0.18):rgba(0,0,0,0)).margin({top:6}).onClick((){this.chooseMenu(idx);})},(item:string,idx:number)idx.toString())}.width(40%).height(100%).backgroundColor(#1f2733).padding({left:12,right:12,top:8})左側菜單欄的結構分為三部分標題區白色大字「我的菜單」上下帶外邊距作為菜單的視覺起點。分隔線Divider組件在標題和菜單項之間畫一條細線顏色為深灰色#3a4657與深色背景形成層次。菜單項列表通過ForEach渲染四個Text菜單項每項寬度 86%、高度 52vp、圓角 8、居中對齊。選中態用主題藍#1a6cff文字 半透明藍背景未選中態用淺灰#cccccc文字 透明背景。整個菜單欄寬度為屏幕的 40%高度 100%深色背景#1f2733帶內邊距。3.7 SideBarContainer 右側主內容區SideBarContainer的第二個子組件是右側主內容區// 右側主內容區Column(){Text(主內容).fontSize(24).fontWeight(FontWeight.Bold).fontColor(#333333).margin({top:80})Text(當前選中this.menus[this.selIdx]).fontSize(14).fontColor(#888888).margin({top:12})Text(點擊下方按鈕打開側滑菜單).fontSize(13).fontColor(#aaaaaa).margin({top:8})Button(打開菜單).width(180).height(46).backgroundColor(#1a6cff).fontColor(Color.White).margin({top:40}).onClick((){this.showtrue;})Column(){Text(功能說明).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#333333)Divider().color(#eeeeee).margin({top:10,bottom:10})Text(1. 點擊打開菜單展開左側菜單).fontSize(13).fontColor(#666666).margin({bottom:6})Text(2. 點擊菜單項可選中并自動收起).fontSize(13).fontColor(#666666).margin({bottom:6})Text(3. 點擊空白區域或返回箭頭也可收起).fontSize(13).fontColor(#666666)}.width(86%).padding(16).backgroundColor(#ffffff).borderRadius(12).margin({top:40})}.width(100%).height(100%).backgroundColor(#f2f3f5)主內容區從上到下依次包含標題區大號「主內容」標題 動態選中狀態文本 操作提示文本垂直排列。打開菜單按鈕藍色主題按鈕寬度 180vp、高度 46vp點擊后設置this.show true展開側邊欄。功能說明卡片白色圓角卡片圓角 12標題「功能說明」下方帶淺色分隔線列出三條使用提示每行間距 6vp。3.8 SideBarContainer 屬性綁定最后是SideBarContainer的屬性綁定部分.width(100%).layoutWeight(1).showSideBar(this.show).onChange((v:boolean){this.showv;})SideBarContainer設置為全寬100%、layoutWeight(1)占滿剩余空間。showSideBar(this.show)綁定狀態變量控制展開/收起onChange回調在側邊欄狀態變化時同步更新this.show。layoutWeight(1)在這里非常關鍵——它確保SideBarContainer占據Column中除頂部返回欄之外的所有剩余空間實現自適應布局。如果不設置layoutWeightSideBarContainer的高度將由內容決定可能無法填滿屏幕。4. 交互流程詳解4.1 打開菜單流程用戶點擊「打開菜單」按鈕觸發以下流程按鈕的onClick回調執行this.show true。State show的變化觸發 ArkUI 的響應式更新機制。SideBarContainer檢測到showSideBar屬性變為true播放滑入動畫展示左側菜單欄。菜單欄從左側滑出覆蓋在主內容區之上。整個過程由 ArkUI 框架自動處理動畫和手勢開發者只需關注狀態的變化。4.2 選中菜單項流程用戶點擊菜單項觸發以下流程菜單項的onClick回調執行this.chooseMenu(idx)。chooseMenu方法更新this.selIdx為點擊的索引。chooseMenu方法設置this.show false觸發側邊欄收起動畫。chooseMenu方法調用promptAction.showToast彈出提示。State selIdx的變化觸發菜單項的樣式重新渲染——選中項變藍色加粗。主內容區的「當前選中」文本同步更新為新選中的菜單項名稱。側邊欄收起完成后onChange回調被觸發this.show被設為false實際上已經是false這一步確保狀態一致。4.3 手勢收起流程用戶通過手勢或點擊菜單外部區域收起側邊欄時ArkUI 框架檢測到收起手勢開始收起動畫。動畫完成后onChange回調被觸發參數v為false。this.show被更新為false與實際狀態保持一致。如果沒有onChange回調this.show仍然是true下次點擊「打開菜單」按鈕時由于showSideBar已經是true不會觸發新的展開動畫導致按鈕失效。5. UI 樣式設計思路5.1 深色側邊欄 淺色內容區示例采用了經典的「深色導航 淺色內容」配色方案側邊欄使用深色背景#1f2733白色文字營造出專業的導航氛圍。主內容區使用淺灰色背景#f2f3f5黑色文字內容區域清晰可讀。選中態使用主題藍#1a6cff在深色和淺色背景上都有良好的視覺效果。這種配色方案的優點是導航區和內容區層次分明用戶可以快速區分兩種功能區域。5.2 選中態視覺反饋選中態通過三重視覺效果區分文字顏色從淺灰色#cccccc變為主題藍#1a6cff。字重從FontWeight.Normal變為FontWeight.Bold。背景色從透明變為半透明藍色rgba(26,108,255,0.18)。三重效果疊加確保選中項在任何背景下都有清晰的視覺反饋。5.3 卡片式布局主內容區的功能說明卡片采用卡片式設計白色背景#ffffff與頁面淺灰色背景形成對比。圓角 12vp視覺柔和。寬度 86%左右留足邊距。內邊距 16vp內容不擁擠。卡片式布局在移動端應用中非常常見它通過邊框、圓角和陰影此示例未添加陰影將相關信息聚合在一起提升了頁面的層次感。6. 運行與測試6.1 運行步驟使用 DevEco Studio 打開項目。運行項目到模擬器或真機。在首頁找到「側滑菜單」示例入口點擊進入。點擊「打開菜單」按鈕觀察側邊欄滑出效果。點擊任意菜單項觀察選中高亮、自動收起、Toast 提示效果。6.2 測試場景測試場景預期結果點擊「打開菜單」按鈕側邊欄從左側滑出點擊菜單項「首頁」菜單項高亮、側邊欄收起、Toast 顯示「點擊了首頁」點擊菜單項「設置」菜單項高亮變為「設置」、主內容區文本更新點擊菜單外部區域側邊欄收起this.show更新為false連續快速點擊菜單項每次都正確切換選中態和收起菜單7. 可擴展方向7.1 Inline 模式適配將SideBarContainerType.Overlay改為SideBarContainerType.Inline即可實現內聯模式側邊欄與主內容區并排顯示。適合平板或橫屏場景可以通過屏幕寬度動態切換模式。7.2 多級菜單當前示例只有一級菜單可以擴展為多級菜單結構。點擊一級菜單項展開二級子菜單使用ForEach嵌套渲染配合動畫效果實現平滑的折疊展開。7.3 菜單圖標為每個菜單項添加圖標使用Row布局 Image/Text組件組合。圖標可以使用系統內置圖標或自定義資源提升菜單的視覺辨識度。7.4 路由導航將菜單項與路由綁定點擊菜單項不僅更新選中態還跳轉到對應的頁面。可以使用router.pushUrl或router.replaceUrl實現頁面導航構建完整的應用導航體系。7.5 持久化選中狀態使用Preferences存儲用戶最后選中的菜單項下次進入頁面時自動高亮上次選中的項提供個性化的用戶體驗。8. 常見問題與調試8.1 側邊欄無法通過按鈕打開問題點擊「打開菜單」按鈕后側邊欄沒有展開。排查檢查show狀態是否正確更新——在onClick回調中添加console.log(this.show)確認。檢查showSideBar(this.show)屬性綁定是否正確。確認沒有在其他地方重置this.show的值。8.2 手勢收起后按鈕失效問題手動滑動收起側邊欄后再次點擊「打開菜單」按鈕無效。排查確認onChange回調是否正確設置。沒有回調時this.show在手勢收起后仍為true導致按鈕無法觸發新的展開。在onChange回調中添加日志確認回調是否被觸發。8.3 菜單項樣式不更新問題點擊菜單項后選中項的高亮樣式沒有更新。排查確認selIdx是否正確更新——在chooseMenu中添加日志。檢查ForEach的鍵值生成器是否穩定。如果 key 不穩定ArkUI 可能無法正確 diff 和重新渲染。確認條件表達式this.selIdx idx是否正確——注意類型比較selIdx是numberidx也是number類型一致。8.4 布局錯亂問題SideBarContainer沒有正確占滿屏幕剩余空間。排查確認SideBarContainer設置了.layoutWeight(1)這是自適應布局的關鍵。檢查父容器Column的高度是否為100%。確認頂部返回欄的高度是固定的不會影響剩余空間的計算。9. 技術總結示例 91 的側滑菜單雖然代碼量不大但涉及了SideBarContainer的核心用法、狀態綁定與雙向同步、動態樣式綁定、列表渲染等多個 ArkUI 關鍵知識點。通過這個示例我們可以總結出抽屜導航的實現范式狀態驅動用一個State boolean變量控制側邊欄的展開/收起。雙向同步同時使用showSideBar屬性和onChange回調確保狀態與 UI 始終一致。動態樣式用三元表達式根據選中索引動態計算組件樣式避免創建額外組件。即時反饋用promptAction.showToast提供輕量級的操作反饋。掌握了這些范式后就可以輕松地將其擴展到多級菜單、路由導航、用戶中心等更復雜的場景中。側滑導航作為移動端應用的基礎導航模式值得每個鴻蒙開發者深入學習和實踐。