今天和各位分享一個博主在實際開發中遇到的問題,以及解決方法。廢話很少說,咱們先來看需求:
咱們要作一個iOS風格的底部菜單彈出組件,具體涉及showCupertinoModalPopup()方法,該方法被執行後,會出現以下圖相似所示的菜單彈出視圖:
相信這個彈出菜單視圖都有見過吧?下面重點來了:在本次的項目需求中,該視圖的選項文字是由Server端返回的。也就是說,這些選項的內容和個數都不固定,所以不能將其在代碼中寫固定值。
爲了簡化代碼以突出重點,下面放上我在一開始的實現方案:測試
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!
這是什麼緣由呢?
實際上,罪魁禍首就在咱們循環遍歷賦值操做時的這條語句:ui
Navigator.pop(context);
這裏的context是整個頁面的BuildContext,而非菜單組的。這裏咱們要明確一個概念——咱們想Pop誰,必定要用誰的BuildContext對象。
在這裏,正確的BuildContext對象是誰呢?它在這裏:debug
showCupertinoModalPopup( context: context, builder: (buildContext) { return CupertinoActionSheet( title: Text('測試菜單'), message: Text('點擊菜單項試試吧!'), actions: menuWidgets); } );
注意到了嗎?上面第三行括號裏的buildContext纔是咱們真正要用的對象。所以,正確的作法是什麼呢?code
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); }); }
如上所示,咱們只需將正確的對象「帶」到其做用域外面就能夠了。
好了,這就是本篇文章的所有內容,但願可以對你有所幫助!對象