Flutter 底部彈窗如何實現(xiàn)多項選擇
多選和單選的不同之處
單選的時候,選中一個就可以直接把結(jié)果返回,因此本身底部彈窗無需狀態(tài)管理。但到多選的時候,需要知道當前選中的選項,有選項被點擊的時候需要存儲下來,當再次被點擊的時候要清空這個選項,同時界面還需要同步更新,因此就涉及到狀態(tài)管理了。
實現(xiàn)方式
在Flutter 中提供了一個 StatefulBuilder 的類,提供了一個 builder方法構(gòu)建有狀態(tài)組件,并且提供了狀態(tài)更新方法,因此在里面完成狀態(tài)管理。
StatefulBuilder(builder: (context1, setState) { return Widget; } )
在這個 builder 方法中,setState 其實就是對應狀態(tài)組件的setState 對應的方法,這個 state 就是用于控制 StatefulBuilder 生成的組件的狀態(tài)的。這種方式有點類似于 React 的 useState 的鉤子函數(shù)用法。
界面變更
首先底部彈窗的頭部組件要更換,需要增加確認按鈕,將構(gòu)建該組件的方法抽離出來如下所示:
Widget _getModalSheetHeaderWithConfirm(String title, {Function onCancel, Function onConfirm}) { return SizedBox( height: 50, child: Row( children: [ IconButton( icon: Icon(Icons.close), onPressed: () { onCancel(); }, ), Expanded( child: Center( child: Text( title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0), ), ), ), IconButton( icon: Icon( Icons.check, color: Colors.blue, ), onPressed: () { onConfirm(); }), ], ), ); }
通過這個方法可以通過外部參數(shù)傳入標題,取消響應事件回調(diào)和確認事件回調(diào),通用性更強。
其次是選項需要有圖標標記,選中時顯示為勾選框,未選中時是空白框,這需要通過狀態(tài)數(shù)據(jù)來控制。這里我們使用了 Set 類型,保證選中的數(shù)據(jù)集是不重復的。在點擊選項時,如果選項對應數(shù)組的下標在 Set 內(nèi),則從中移出,表示取消選擇;如果不在 Set內(nèi),則加入其中,表示選中。這個過程需要包在 state 里,以更新界面。通過列表元素當前的下標是否在 Set 內(nèi),如果在則顯示為選中,不在則顯示未選中。
最后是確認事件的回調(diào),確認后將 Set 的元素轉(zhuǎn)換為數(shù)組返回,然后供上級業(yè)務使用選中的下標數(shù)組判斷選擇了那些數(shù)據(jù)。
代碼實現(xiàn)
關(guān)鍵代碼實現(xiàn)如下,重點關(guān)注一下StatefulBuilder的使用和利用 Set 這一數(shù)據(jù)類型對應的選擇和取消選擇的操作業(yè)務邏輯。
Future<List<int>> _showMultiChoiceModalBottomSheet( BuildContext context, List<String> options) async { Set<int> selected = Set<int>(); return showModalBottomSheet<List<int>>( backgroundColor: Colors.transparent, isScrollControlled: true, context: context, builder: (BuildContext context) { return StatefulBuilder(builder: (context1, setState) { return Container( clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: const Radius.circular(20.0), topRight: const Radius.circular(20.0), ), ), height: MediaQuery.of(context).size.height / 2.0, child: Column(children: [ _getModalSheetHeaderWithConfirm('多選底部彈窗', onCancel: () { Navigator.of(context).pop(); }, onConfirm: () { Navigator.of(context).pop(selected.toList()); }, ), Divider(height: 1.0), Expanded( child: ListView.builder( itemBuilder: (BuildContext context, int index) { return ListTile( trailing: Icon( selected.contains(index) ? Icons.check_box : Icons.check_box_outline_blank, color: Theme.of(context).primaryColor), title: Text(options[index]), onTap: () { setState(() { if (selected.contains(index)) { selected.remove(index); } else { selected.add(index); } }); }, ); }, itemCount: options.length, ), ), ]), ); }); }, ); }
總結(jié)
本篇介紹了底部彈窗實現(xiàn)多選的方式,其中實現(xiàn)的方式還可以有很多種,例如直接在自定義組件中使用有狀態(tài)組件。這里介紹的方法可以作為一個參考,通過動態(tài)構(gòu)建有狀態(tài)組件能夠簡單快速地實現(xiàn)底部彈窗的多選功能。
以上就是Flutter 底部彈窗如何實現(xiàn)多項選擇的詳細內(nèi)容,更多關(guān)于Flutter 底部彈窗實現(xiàn)多項選擇的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)解決popupWindow重疊報錯問題
今天小編就為大家分享一篇關(guān)于Android開發(fā)解決popupWindow重疊報錯問題的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Android百度地圖定位后獲取周邊位置的實現(xiàn)代碼
這篇文章主要為大家詳細介紹了Android百度地圖定位后獲取周邊位置的實現(xiàn)代碼,準確獲取周邊地理位置,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-01-01Android設(shè)備上非root的抓包實現(xiàn)方法(Tcpdump方法)
通常我們在Android應用中執(zhí)行某個命令時會使用“Runtime.getRuntime().exec("命令路徑")”這種方式,但是當我們執(zhí)行抓包操作時,使用這條命令無論如何都不行,通過下面代碼打印結(jié)果發(fā)現(xiàn),該命令一定要在root權(quán)限下才能執(zhí)行,具體實現(xiàn)思路,請參考本教程2016-11-11Android開發(fā)實現(xiàn)的Intent跳轉(zhuǎn)工具類實例
這篇文章主要介紹了Android開發(fā)實現(xiàn)的Intent跳轉(zhuǎn)工具類,簡單描述了Intent組件的功能并結(jié)合實例形式給出了頁面跳轉(zhuǎn)、拍照、圖片調(diào)用等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11