Reputation: 24908
Here is a material design of Expanded panel
that looks like:
I'd like to make a similar one with Flutter
, not sure if I've to start with something like the below code or know, and how to complete it!
new ExpansionPanelList(
children: <ExpansionPanel>[
new ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
isExpanded = true;
return new ListTile(
// leading: item.iconpic,
title: new Text(
"First",
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
));
},
body: new Text("school"),
isExpanded: true,
),
new ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
isExpanded = true;
return new ListTile(
// leading: item.iconpic,
title: new Text(
"Second",
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
));
},
isExpanded: false,
body: new Text("hospital"),
),
new ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
isExpanded = true;
return new ListTile(
// leading: item.iconpic,
title: new Text(
"Third",
textAlign: TextAlign.left,
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
));
},
body: new Text("va facility"),
isExpanded: true)
]),
UPDATE
I just need to start and have the empty panels
Upvotes: 1
Views: 13882
Reputation: 53307
In case if you particularly need to mimic the images you referenced from the material design. You would want to build your own custom expansion panel.
I have a simple example using AnimatedContainer
to show you how to create the expanded and collapsed effects, and it is up to you to populate both the header and the body sections with what you want.
class AnimateExpanded extends StatefulWidget {
@override
_AnimateExpandedState createState() => new _AnimateExpandedState();
}
class _AnimateExpandedState extends State<AnimateExpanded> {
double _bodyHeight = 0.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey[500],
body: new SingleChildScrollView(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Card(
child: new Container(
height: 50.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new IconButton(
icon: new Icon(Icons.keyboard_arrow_down),
onPressed: () {
setState(() {
this._bodyHeight = 300.0;
});
},
)
],
),
),
),
new Card(
child: new AnimatedContainer(
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new IconButton(
icon: new Icon(Icons.keyboard_arrow_up),
onPressed: () {
setState(() {
this._bodyHeight = 0.0;
});
},
),
],
),
curve: Curves.easeInOut,
duration: const Duration(milliseconds: 500),
height: _bodyHeight,
// color: Colors.red,
),
),
],
),
),
);
}
}
Upvotes: 6
Reputation: 4678
You can use ExpansionTile
inside ListView
like this
ListView(
shrinkWrap: true,
children: <Widget>[
ExpansionTile(
backgroundColor: Colors.amber,
leading: Icon(Icons.event),
title: Text('Test1'),
children: <Widget>[
ListTile(title: Text('Title of the item')),
ListTile(
title: Text('Title of the item2'),
)
],
),
ExpansionTile(
title: Text('Test2'),
children: <Widget>[
ListTile(title: Text('Title of the item')),
ListTile(
title: Text('Title of the item2'),
)
],
)
],
)
Upvotes: 3
Reputation: 40423
Here's a working example (including main etc so you can just paste into a file and run)
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ListItem {
final WidgetBuilder bodyBuilder;
final String title;
final String subtitle;
bool isExpandedInitially;
ListItem({
@required this.bodyBuilder,
@required this.title,
this.subtitle = "",
this.isExpandedInitially = false,
}) : assert(title != null),
assert(bodyBuilder != null);
ExpansionPanelHeaderBuilder get headerBuilder =>
(context, isExpanded) => new Row(children: [
new SizedBox(width: 100.0, child: new Text(title)),
new Text(subtitle)
]);
}
class ExpansionList extends StatefulWidget {
/// The items that the expansion list should display; this can change
/// over the course of the object but probably shouldn't as it won't
/// transition nicely or anything like that.
final List<ListItem> items;
ExpansionList(this.items) {
// quick check to make sure there's no duplicate titles.
assert(new Set.from(items.map((li) => li.title)).length == items.length);
}
@override
State<StatefulWidget> createState() => new ExpansionListState();
}
class ExpansionListState extends State<ExpansionList> {
Map<String, bool> expandedByTitle = new Map();
@override
Widget build(BuildContext context) {
return new ExpansionPanelList(
children: widget.items
.map(
(item) => new ExpansionPanel(
headerBuilder: item.headerBuilder,
body: new Builder(builder: item.bodyBuilder),
isExpanded:
expandedByTitle[item.title] ?? item.isExpandedInitially),
)
.toList(growable: false),
expansionCallback: (int index, bool isExpanded) {
setState(() {
expandedByTitle[widget.items[index].title] = !isExpanded;
});
},
);
}
}
void main() => runApp(
new MaterialApp(
home: new SingleChildScrollView(
child: new SafeArea(
child: new Material(
child: new ExpansionList(
[
new ListItem(
title: "Title 1",
subtitle: "Subtitle 1",
bodyBuilder: (context) => new Text("Body 1")),
new ListItem(
title: "Title 2",
subtitle: "Subtitle 2",
bodyBuilder: (context) => new Text("Body 1"),
isExpandedInitially: true)
],
),
),
),
),
),
);
If I had to guess, you're missing the parts where you pass in expanded into each expansion header, and the part where you keep track of whether each expansion header is expanded or not.
I've done it a particular way here that assumes each title is unique; you could do something similar but rely on different properties. Or you could build everything in the initState method of your ExpansionListState equivalent.
This is a full working example of pretty much the exact UI you have in the picture in your post. You can simply download the flutter gallery from the play store to see the result. They did it a different way than I did (building everything in the initState method), and it's more complicated than what I did, but would be worth understanding as well.
Hope that helps =)
Upvotes: 2