You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:48:29