Flutter中如何实现ExpansionPanel点击头部展开折叠
问题根因
现有实现缺两个必要配置,导致点击头部无法触发展开/折叠:
ExpansionPanel的isExpanded被硬编码为固定值true,没有和组件状态绑定,状态变更不会触发UI更新ExpansionPanelList未配置expansionCallback回调,点击头部时框架接收不到状态变更通知,不会执行交互逻辑
修改方案
- 在
_MyHomePageState类中新增状态变量,存储面板的展开状态 - 给
ExpansionPanelList传入expansionCallback回调,点击触发时通过setState更新面板状态 - 将
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
相关产品推荐
相关产品推荐

