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

Flutter中如何实现ExpansionPanel点击头部展开折叠

问题根因

现有实现缺两个必要配置,导致点击头部无法触发展开/折叠:

  • ExpansionPanel的isExpanded被硬编码为固定值true,没有和组件状态绑定,状态变更不会触发UI更新
  • ExpansionPanelList未配置expansionCallback回调,点击头部时框架接收不到状态变更通知,不会执行交互逻辑
修改方案
  1. 在_MyHomePageState类中新增状态变量,存储面板的展开状态
  2. 给ExpansionPanelList传入expansionCallback回调,点击触发时通过setState更新面板状态
  3. 将ExpansionPanel的isExpanded属性绑定到自定义的状态变量,禁止写死固定值

修改后可正常运行的完整代码:

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(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 存储Todo面板的展开状态
  bool _isTodoExpanded = true;

  Widget buildNewTasks(BuildContext context) {
    return ListView.builder(
      scrollDirection: Axis.vertical,
      shrinkWrap: true,
      itemCount: 2,
      itemBuilder: (BuildContext context, int index) {
        return Text(index.toString());
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
      children: [
        ExpansionPanelList(
          // 监听面板点击事件,更新展开状态
          expansionCallback: (panelIndex, isExpanded) {
            setState(() {
              _isTodoExpanded = !isExpanded;
            });
          },
          children: [
            ExpansionPanel(
                headerBuilder: (context, isExpanded) {
                  return ListTile(
                    title: Text("Todo"),
                  );
                },
                body: buildNewTasks(context),
                // 绑定状态变量,不再硬编码
                isExpanded: _isTodoExpanded,
                canTapOnHeader: true),
          ],
        )
      ],
    ));
  }
}

补充:如果需要渲染多个ExpansionPanel,直接用列表存储每个面板的展开状态即可,回调中通过传入的panelIndex参数定位要更新的对应面板。

内容的提问来源于stack exchange,提问作者Dolphin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:48:24