變更 RawMenuAnchor 的關閉順序
關閉 `RawMenuAnchor` 現在會以協調的順序觸發所有 後代 `RawMenuAnchor` 的 `onClose` 與 `onCloseRequested` 回呼(callback)。
摘要
#
關閉 RawMenuAnchor 現在會觸發所有後代 RawMenuAnchor 的
onCloseRequested 與 onClose 回呼(callback)。
onCloseRequested 回呼會由上而下觸發,
從觸發的 RawMenuAnchor 開始,依序傳遞至其後代,
而 onClose 回呼則由下而上觸發。
若 RawMenuAnchor 已處於關閉狀態,
呼叫 MenuController.close 與 MenuController.closeChildren
不會觸發 onCloseRequested 回呼。
背景
#
RawMenuAnchor 是一個用於建置自訂選單系統的低階元件 (Widget)。
先前,RawMenuAnchor 在關閉時不會自動通知其後代。
您必須在 onCloseRequested 回呼中手動呼叫 controller.closeChildren(),
才能關閉後代的 RawMenuAnchor。
此外,onClose 回呼的觸發時機並不一致。
父級 RawMenuAnchor 的 onClose 可能在其後代完成關閉之前就已執行。
更新後的行為確保當父級 RawMenuAnchor 開始關閉時,
會以由上而下的方式依序觸發所有後代 RawMenuAnchor 的 onCloseRequested。
當在 onCloseRequested 中呼叫 hideOverlay 來關閉選單時,
所有後代 RawMenuAnchor 的 onClose 回呼會以由下而上的順序執行。
這表示最近開啟的 RawMenuAnchor 的 onClose 回呼會最先執行,
接著才是其父級,依此類推,直到層級頂端。
此設計允許以協調的關閉順序進行操作,
讓子級 RawMenuAnchor 在其父級完成關閉流程之前,
能夠先執行必要的清理作業。
最後,若 RawMenuAnchor 已處於關閉狀態,
呼叫 MenuController.close 與 MenuController.closeChildren
不會觸發 onCloseRequested 回呼,以避免不必要的回呼執行。
遷移指南
#
若您的程式碼未覆寫 RawMenuAnchor.onCloseRequested 的預設實作,
或您的 RawMenuAnchor 不包含子選單,則無需進行任何變更。
若您在包含子選單的 RawMenuAnchor 中
自訂了 onCloseRequested 的實作,
則當父選單關閉時,controller.closeChildren() 現在會自動呼叫。
請確認您的 onCloseRequested 實作在這個自動呼叫的情況下仍能正常運作。
在您的 onCloseRequested 回呼中直接呼叫 controller.closeChildren()
已不再必要,請移除這些呼叫。
此外,若您的邏輯依賴父級的 onClose 回呼在後代之前觸發,
請重構您的程式碼以適應新的由下而上的執行順序。
遷移前的程式碼:
RawMenuAnchor(
controller: menuController,
onCloseRequested: (hideOverlay) {
if (!animationController.isForwardOrCompleted) {
return;
}
// Descendant submenus must be closed before the parent menu.
// This is now handled automatically, so this call is no longer necessary.
menuController.closeChildren();
animationController.reverse().whenComplete(hideOverlay);
},
onClose: () {
// This might have executed before descendants called onClose().
_handleMenuClosed();
},
// ...
)
遷移後的程式碼:
RawMenuAnchor(
controller: menuController,
onCloseRequested: (hideOverlay) {
if (!animationController.isForwardOrCompleted) {
return;
}
// `menuController.closeChildren()` is now called automatically.
animationController.reverse().whenComplete(hideOverlay);
},
onClose: () {
// This now executes only after all descendant submenus have
// called `onClose()`.
_handleMenuClosed();
},
// ...
)
時間軸
#
導入版本:3.44.0-0.1.pre
穩定版發布:3.44
參考資料
#API 文件:
相關 issue:
相關 PR:
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-06-14. View source or report an issue.