Flutter Expansion Panel
Creating expandable and collapsible content
🔽 What is Expansion Panel?
ExpansionPanel creates collapsible sections that expand to reveal more content. It's great for FAQs, settings menus, or organizing information in a compact, user-friendly way.
// Simple ExpansionPanelList
ExpansionPanelList(
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return Text('Title');
},
body: Text('Content'),
),
],
)
Expansion Panel Components
ExpansionPanelList
Container for panels
ExpansionPanelList(
expansionCallback: (index, isExpanded) {
// Handle expansion
},
children: [],
)
ExpansionPanel
Individual panel item
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return Text('Header');
},
body: Text('Body'),
isExpanded: false,
)
headerBuilder
Builds panel header
headerBuilder: (context, isExpanded) {
return ListTile(
title: Text('Title'),
);
}
body
Panel content
body: Container(
padding: EdgeInsets.all(16),
child: Text('Details here'),
)
🔹 Basic Expansion Panel Example
Create a simple FAQ with expandable panels:
import 'package:flutter/material.dart';
class Item {
String header;
String body;
bool isExpanded;
Item(this.header, this.body, this.isExpanded);
}
class MyExpansionPanel extends StatefulWidget {
@override
_MyExpansionPanelState createState() => _MyExpansionPanelState();
}
class _MyExpansionPanelState extends State<MyExpansionPanel> {
List<Item> items = [
Item('What is Flutter?', 'Flutter is a UI toolkit for building apps.', false),
Item('Is Flutter free?', 'Yes, Flutter is completely free and open-source.', false),
Item('What languages does Flutter use?', 'Flutter uses Dart programming language.', false),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('FAQ')),
body: SingleChildScrollView(
child: ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
items[index].isExpanded = !isExpanded;
});
},
children: items.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(item.header),
);
},
body: ListTile(
title: Text(item.body),
),
isExpanded: item.isExpanded,
);
}).toList(),
),
),
);
}
}
Output:
What is Flutter?
▼
Is Flutter free?
▼
What languages does Flutter use?
▼
🔹 Styled Expansion Panel
Create a more visually appealing expansion panel:
ExpansionPanelList(
elevation: 2,
expandedHeaderPadding: EdgeInsets.all(0),
expansionCallback: (int index, bool isExpanded) {
setState(() {
items[index].isExpanded = !isExpanded;
});
},
children: items.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
backgroundColor: Colors.blue[50],
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
leading: Icon(Icons.help_outline, color: Colors.blue),
title: Text(
item.header,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue[900],
),
),
);
},
body: Container(
padding: EdgeInsets.all(16),
color: Colors.white,
child: Text(
item.body,
style: TextStyle(fontSize: 14),
),
),
isExpanded: item.isExpanded,
);
}).toList(),
)
Output:
❓
What is Flutter?
Flutter is a UI toolkit for building apps.
🔹 ExpansionTile Alternative
Use ExpansionTile for simpler expandable content:
class SimpleExpansion extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: [
ExpansionTile(
leading: Icon(Icons.person),
title: Text('Account Settings'),
children: [
ListTile(
title: Text('Change Password'),
leading: Icon(Icons.lock),
),
ListTile(
title: Text('Update Email'),
leading: Icon(Icons.email),
),
],
),
ExpansionTile(
leading: Icon(Icons.notifications),
title: Text('Notifications'),
children: [
SwitchListTile(
title: Text('Push Notifications'),
value: true,
onChanged: (bool value) {},
),
SwitchListTile(
title: Text('Email Notifications'),
value: false,
onChanged: (bool value) {},
),
],
),
],
);
}
}
Output:
👤
Account Settings
▼
🔔
Notifications
▼
🔹 Expansion Panel Best Practices
Tips for using Expansion Panels:
- Use ExpansionTile for simpler cases
- Keep headers concise - Clear and descriptive
- Manage state properly - Track expanded state
- Add visual feedback - Icons or colors for expanded state
- Consider SingleChildScrollView for many panels