如何在ExpansionPanelList中嵌入RadioButton或菜单项列表?
在ExpansionPanelList中嵌入单选按钮与菜单项
1. 调整数据结构
首先修改原有数据,为每个折叠面板添加可选选项集合,以及存储选中状态的字段:
final List<Map<String, dynamic>> _items = List.generate( 5, (index) => { 'id': index, 'title': '选项组 $index', 'options': ['选项A', '选项B', '选项C', '选项D'], 'selectedOption': null, // 记录当前选中的选项 'isExpanded': false });
2. 替换折叠面板的内容区域
将原有ExpansionPanel的body部分从单纯的文本替换为单选按钮列表,同时处理选中状态的更新逻辑:
children: _items.asMap().entries.map((entry) { final index = entry.key; final item = entry.value; return ExpansionPanel( canTapOnHeader: true, backgroundColor: item['isExpanded'] ? Colors.grey[100] : Colors.white, headerBuilder: (_, isExpanded) => Container( padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 30), child: Text( item['title'], style: const TextStyle(fontSize: 20), ), ), // 替换body为单选按钮列表 body: Container( padding: const EdgeInsets.symmetric(horizontal: 15), child: Column( children: item['options'] .map((option) => RadioListTile( title: Text(option), value: option, groupValue: item['selectedOption'], onChanged: (value) { setState(() { item['selectedOption'] = value; }); }, )) .toList(), ), ), isExpanded: item['isExpanded'], ); }).toList(),
3. 完整可运行代码
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Expansion Radio', theme: ThemeData( primarySwatch: Colors.indigo, ), home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final List<Map<String, dynamic>> _items = List.generate( 5, (index) => { 'id': index, 'title': '选项组 $index', 'options': ['选项A', '选项B', '选项C', '选项D'], 'selectedOption': null, 'isExpanded': false }); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Expansion List'), ), body: SingleChildScrollView( child: ExpansionPanelList( elevation: 3, expansionCallback: (index, isExpanded) { setState(() { _items[index]['isExpanded'] = !isExpanded; }); }, animationDuration: const Duration(milliseconds: 600), children: _items.asMap().entries.map((entry) { final index = entry.key; final item = entry.value; return ExpansionPanel( canTapOnHeader: true, backgroundColor: item['isExpanded'] ? Colors.grey[100] : Colors.white, headerBuilder: (_, isExpanded) => Container( padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 30), child: Text( item['title'], style: const TextStyle(fontSize: 20), ), ), body: Container( padding: const EdgeInsets.symmetric(horizontal: 15), child: Column( children: item['options'] .map((option) => RadioListTile( title: Text(option), value: option, groupValue: item['selectedOption'], onChanged: (value) { setState(() { item['selectedOption'] = value; }); }, )) .toList(), ), ), isExpanded: item['isExpanded'], ); }).toList(), ), ), ); } }
拓展:嵌入其他类型菜单项
如果需要添加其他交互项,只需替换RadioListTile为对应组件即可:
- 复选框:使用
CheckboxListTile,数据结构改为存储选中选项列表(如'selectedOptions': []),在onChanged中添加/移除选项 - 普通点击项:使用
ListTile,通过onTap回调处理点击逻辑 - 按钮项:直接使用
ElevatedButton/TextButton自定义交互
内容的提问来源于stack exchange,提问作者GoodMan
相关产品推荐
相关产品推荐

