Flutter group listviews with separator
A much cleaner and simple solution would be to use the following
ListView.separated(
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
itemCount: 20,
itemBuilder: (context, index) => Padding(
padding: EdgeInsets.all(8.0),
child: Center(child: Text("Index $index")),
),
)
simply put the ListItem
into a Container
and add decoration:
@override
Widget build(BuildContext context) {
return new Container(
child: new ListTile(
title: new Text('I have border')
),
decoration:
new BoxDecoration(
border: new Border(
bottom: new BorderSide()
)
)
);
}
I apologize for the ugliness of the design, but just to show you, you can pretty much build your own design that you desire, this a quick example:
import "package:flutter/material.dart";
import 'package:meta/meta.dart';
class Test extends StatefulWidget {
@override
_TestState createState() => new _TestState();
}
class _TestState extends State<Test> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Test"),
),
body: new ListView.builder(
// itemCount: myData.lenght(),
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
//sort my data by timestamp before building
return new CustomWidget(date: "Convert my time stamp to date",
content: "My Awesome Content",
trailingIconOne: new Icon(Icons.share, color: Colors.blueAccent,),
trailingIconTwo: new Icon(
Icons.favorite, color: Colors.redAccent,),);
}),
);
}
}
class CustomWidget extends StatelessWidget {
String date;
String content;
Icon trailingIconOne;
Icon trailingIconTwo;
CustomWidget(
{@required this.date, @required this.content, @required this.trailingIconOne, @required this.trailingIconTwo});
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
border: new Border.all(color: Colors.grey[500])
),
child: new Column(
children: <Widget>[
new Container (child: new Text(date), color: Colors.yellow[200],),
new Container(height: 15.0,),
new Text(content),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new IconButton(icon: trailingIconOne, onPressed: () {}),
new Container(width: 10.0,),
new IconButton(icon: trailingIconTwo, onPressed: () {})
],
)
],
),
);
}
}
For a better design, you can get rid of the borders and use a Divider
instead:
return new Container(
child: new Column(
children: <Widget>[
new Column (children: <Widget>[
new Container (child: new Text(date), color: Colors.yellow[200],),
new Container(height: 15.0,),
new Text(content),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new IconButton(icon: trailingIconOne, onPressed: () {}),
new Container(width: 10.0,),
new IconButton(icon: trailingIconTwo, onPressed: () {}),
], ),
new Divider(height: 15.0,color: Colors.red,),
],
)
],
),
And a better visual solution in my opinion is to use a Card
instead of Container
,
return new Card(
child: new Column(
children: <Widget>[
new Column (children: <Widget>[
new Container (child: new Text(date), color: Colors.yellow[200],),
new Container(height: 15.0,),
new Text(content),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new IconButton(icon: trailingIconOne, onPressed: () {}),
new Container(width: 10.0,),
new IconButton(icon: trailingIconTwo, onPressed: () {}),
], ),
// new Divider(height: 15.0,color: Colors.red,),
],
)
],
),
);