如何在ListView.builder中配置独立的CustomPopupMenuController
问题根源
你当前的写法核心错误是把CustomPopupMenuController实例转成字符串传入模型类,这完全不是插件需要的控制器实例;同时复用同一个_controller对象,导致所有列表项共用同一控制器,弹窗状态混乱。
正确实现方案
不需要额外的模型类,直接维护一个List<CustomPopupMenuController>即可,每个列表项对应独立的控制器实例:
1. 初始化控制器列表
// 直接用List存储控制器,无需额外封装 List<CustomPopupMenuController> controllers = [];
2. 加载数据时创建独立控制器
在getAllMessages方法中,每添加一条交易数据,同时创建新的控制器实例:
void getAllMessages() { Future.delayed(Duration.zero, () async { List<SmsMessage> messages = await query.querySms( kinds: [SmsQueryKind.inbox], count: 200, address: "MPESA", ); setState(() { transactions.clear(); controllers.clear(); // 清空旧控制器避免冗余 allmessages = messages; for (var element in allmessages) { String message = element.body.toString(); if ((RawData.getMode(message) == 1 || RawData.getMode(message) == 2 || RawData.getMode(message) == 3 || RawData.getMode(message) == 4) && RawData.getTime(message) != 'ERR') { transactions.add( TransData( receiver: RawData.getReceiver(message), code: RawData.getTransactionCode(message), amount: RawData.getAmount(message), paymentMode: RawData.getModeName(message), time: RawData.getTime(message), date: RawData.getDate(message), phone: RawData.getSendMonmeyNumber(message), accountNumber: RawData.getPayBillAccountNumber(message), message: message, ), ); // 为当前列表项创建全新的控制器实例 controllers.add(CustomPopupMenuController()); } } }); }); }
3. 在ListView.builder中绑定对应控制器
通过列表索引获取当前项的控制器:
ListView.builder( itemCount: transactions.length, itemBuilder: (context, index) { final itemController = controllers[index]; return CustomPopupMenu( controller: itemController, menuBuilder: () => // 你的自定义菜单布局, child: // 列表项UI组件, ); }, )
4. 清理控制器避免内存泄漏
在页面销毁时,遍历列表释放所有控制器资源:
@override void dispose() { for (var controller in controllers) { controller.dispose(); } super.dispose(); }
可选:保留自定义模型类的写法
如果一定要用你定义的MyCustomPopupController,修正使用逻辑即可:
// 模型类保持不变 class MyCustomPopupController { final CustomPopupMenuController controller; MyCustomPopupController({required this.controller}); } // 初始化列表 List<MyCustomPopupController> controllers = []; // 添加控制器时传入新实例 controllers.add(MyCustomPopupController(controller: CustomPopupMenuController())); // ListView中调用 final itemController = controllers[index].controller;
内容的提问来源于stack exchange,提问作者Benson Karue
相关产品推荐
相关产品推荐

