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