To begin with, i have the CustomExpansionPanelList
widget as a parent. Then a list of children of the CustomExpansionPanel
. In the headerBuilder
is the ListTile
, which has text and an icon on trailing.
The problem: the onPressed
event is hard to catch by the CustomExpansionPanel
. A specific tap must be done.
Note: CustomExpansionPanelList
and CustomExpansionPanel
are classes modified by me. Removing the 'Custom' you get the classes of the widget itself.
The code:
CustomExpansionPanelList(
elevation: 0,
expandedHeaderPadding: EdgeInsets.zero,
expansionCallback: (i, isOpen) {
///some code
},
children: [
CustomExpansionPanel(
canTapOnHeader: true,
isExpanded: true,
body: const SomeBody(),
headerBuilder: (context, isOpen) {
return ListTile(
iconColor: Colors.white,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20.0),
title: const Text(
'some text',
),
trailing: Transform.translate(
offset: const Offset(30, 0),
child: Container(
margin: EdgeInsets.all(8),
child: IconButton(
icon: Icon(Icons.edit_outlined),
onPressed: () => someAction()
)),
)));
},
),
])
You could just set canTapOnHeader: false
in the CustomExpansionPanel
widget. That way taps on your IconButton
in the header are registered correctly, and you can expand/collapse the body of the CustomExpansionPanel
by tapping on the little arrow icon to the right of your IconButton
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<bool> panelIsExpanded = [true];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: ExpansionPanelList(
elevation: 0,
expandedHeaderPadding: EdgeInsets.zero,
expansionCallback: (panelIndex, isExpanded) => setState(() {
panelIsExpanded[panelIndex] = !panelIsExpanded[panelIndex];
}),
children: [
ExpansionPanel(
canTapOnHeader: false,
isExpanded: panelIsExpanded[0],
body: const Text('This is the body of the expansion panel'),
headerBuilder: (context, isOpen) {
return ListTile(
iconColor: Colors.black,
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: const Text(
'some text',
),
trailing: Transform.translate(
offset: const Offset(30, 0),
child: Container(
margin: const EdgeInsets.all(8),
child: IconButton(
icon: const Icon(Icons.edit_outlined),
onPressed: () =>
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'You tapped the edit icon on the header of the expansion panel'),
),
),
),
),
),
);
},
),
],
),
),
);
}
}