今天和各位分享一個博主在實際開發中遇到的問題,以及解決方法。廢話很少說,咱們先來看需求:
咱們要作一個iOS風格的底部菜單彈出組件,具體涉及showCupertinoModalPopup()方法,該方法被執行後,會出現以下圖相似所示的菜單彈出視圖:
bash
openActionSheet() {
List<Widget> menuWidgets = new List();
menuItems.forEach((element) {
menuWidgets.add(CupertinoActionSheetAction(
child: Text(element),
onPressed: () {
Navigator.pop(context);
debugPrint("操做$element被執行「); }, isDefaultAction: true, )); }); showCupertinoModalPopup( context: context, builder: (buildContext) { return CupertinoActionSheet( title: Text('測試菜單'), message: Text('點擊菜單項試試吧!'), actions: menuWidgets); }); } 複製代碼
如上述代碼所示,openActionSheet()是顯示該組件的方法。其中,showCupertinoModalPopup()爲Flutter SDK內置方法,其做用即顯示這個組件;再其上面的循環以及List聲明、賦值等操做實際上就是在動態添加菜單項。menuItems類型是List<String>。
經過對代碼的解釋,相信你們可以一目瞭然地看出,當某個菜單項被點擊時,整個菜單組件消失,並打印Debug Log(對應爲真實項目要執行的操做)。
你們以爲上述代碼有問題嗎?若是有問題,問題在哪兒呢?
如今公佈答案:這段代碼有問題!
上述代碼執行時,當用戶點擊菜單項後,其運行結果並不是如咱們預想的那樣:菜單組消失並輸出Log,而變成了:整個頁面被Pop,菜單組保留,並輸出Log!
這是什麼緣由呢?
實際上,罪魁禍首就在咱們循環遍歷賦值操做時的這條語句:測試
Navigator.pop(context);
複製代碼
這裏的context是整個頁面的BuildContext,而非菜單組的。這裏咱們要明確一個概念——咱們想Pop誰,必定要用誰的BuildContext對象。
在這裏,正確的BuildContext對象是誰呢?它在這裏:ui
showCupertinoModalPopup(
context: context,
builder: (buildContext) {
return CupertinoActionSheet(
title: Text('測試菜單'),
message: Text('點擊菜單項試試吧!'),
actions: menuWidgets);
}
);
複製代碼
注意到了嗎?上面第三行括號裏的buildContext纔是咱們真正要用的對象。所以,正確的作法是什麼呢?spa
openActionSheet() {
BuildContext tempContext;
List<Widget> menuWidgets = new List();
menuItems.forEach((element) {
menuWidgets.add(CupertinoActionSheetAction(
child: Text(element),
onPressed: () {
Navigator.pop(tempContext);
debugPrint("操做$element被執行");
},
isDefaultAction: true,
));
});
showCupertinoModalPopup(
context: context,
builder: (buildContext) {
tempContext = buildContext;
return CupertinoActionSheet(
title: Text('測試菜單'),
message: Text('點擊菜單項試試吧!'),
actions: menuWidgets);
});
}
複製代碼
如上所示,咱們只需將正確的對象「帶」到其做用域外面就能夠了。
好了,這就是本篇文章的所有內容,但願可以對你有所幫助!debug