使用ValueListenableBuilder时如何自动关闭内含RadioListTile的PopupMenuButton
修复方案
核心逻辑是在RadioListTile的选中回调里主动触发弹窗关闭,同时修复原代码中状态放在build方法导致每次重建会重置选中值的问题,完整修改后的代码如下:
import 'package:flutter/material.dart'; void main() => runApp( MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( actions: [ SelectionPopupMenu(), ], ), ), ), ); // 改为StatefulWidget存储持久状态 class SelectionPopupMenu extends StatefulWidget { @override State<SelectionPopupMenu> createState() => _SelectionPopupMenuState(); } class _SelectionPopupMenuState extends State<SelectionPopupMenu> { final _selectionList = ['First', 'Second']; final _selectedValueNotifier = ValueNotifier(0); @override Widget build(BuildContext context) { return PopupMenuButton<int>( itemBuilder: (context) => List.generate( _selectionList.length, (index) => PopupMenuItem( // 给PopupMenuItem设置value,兼容原有onSelected逻辑 value: index, child: ValueListenableBuilder( valueListenable: _selectedValueNotifier, builder: (context, value, child) => RadioListTile<int>( value: index, title: Text(_selectionList[index]), groupValue: _selectedValueNotifier.value, onChanged: (value) { _selectedValueNotifier.value = value!; // 主动关闭弹窗,等同于onSelected触发后的默认关闭逻辑 Navigator.pop(context, value); }, ), ), ), ), // 可选:保留onSelected回调处理后续业务逻辑 onSelected: (value) { debugPrint('选中了索引为$value的选项:${_selectionList[value]}'); }, ); } }
修改说明
- 把组件改为StatefulWidget,将选项列表和状态监听实例移到State中,避免每次Widget重建时状态被重置
- 在RadioListTile的
onChanged回调更新完选中状态后,调用Navigator.pop(context, value)手动关闭弹窗,传入的value会自动触发PopupMenuButton的onSelected回调,兼容原有业务逻辑 - 给每个PopupMenuItem设置对应value,保证onSelected回调可以正常拿到选中值
内容的提问来源于stack exchange,提问作者Burhan Khanzada
相关产品推荐
相关产品推荐

