I have ListView and need to insert few headers in current position (index). But if I use approach from billow ,my index not in order,I lose 1st and last place from list...
if I add itemCount: _list.length + 1, and latter index -= 1; I got first section right but that not working for next header..
class CheckList extends StatefulWidget {
bool isCheck = false; //for checkbox
final String value; //geting value from other class
List<String> _list = [];
final List<ListItem> items;
CheckList({Key key, this.value, this.items}) : super(key: key);
@override
_Question createState() => _Question();
}
class _Question extends State<CheckList> {
BuildContext context;
_getFromDB() async {
widget._list = await DB().get2(widget.value, 'Description');
widget._list.insert(0, "Part 1:...");
widget._list.insert(18, "Part 2:...");
widget._list.insert(49, "Part 3:...");
final List<ListItem> items = widget._list.map((value) {
final index = widget._list.indexOf(value);
if ([0, 18, 49].contains(index)) {
return HeaderItem(value);
} else {
return MessageItem(value);
}
}).toList();
setState(() {});
}
@override
Widget build(BuildContext context) {
this.context = context;
return Scaffold(
appBar: AppBar(
title: Text(
'TITLE APP',
),
),
body: Container(
child: getListView(), //listview populated from db
));
}
Widget getListView() {
_getFromDB();
var listview = ListView.builder(
itemCount: widget.items.length,
itemBuilder: (context, index) {
final item = widget.items[index];
if (item is HeaderItem) {
return Column(
children: <Widget>[
Text(
item.heading,
),
Divider(),
],
);
} else if (item is MessageItem) {
return ListTile(
dense: true,
leading: Checkbox(
value: item.checked,
onChanged: (value) {
setState(() {
item.checked = value;
});
},
),
title: Text(
item.title,
),
// subtitle: Text(_list2[index]),
);
}
},
);
return listview;
}
}
abstract class ListItem {}
class HeaderItem implements ListItem {
final String heading;
HeaderItem(this.heading);
}
class MessageItem implements ListItem {
final String title;
bool checked = false;
MessageItem(this.title);
}
So how to correct index nubers and show all items from list with inserted headers..
You could use this approach...
Create classes that will represent different item types (HeaderItem
,MessageItem
), then map _list
to list of items (you will need to have header values inside your _list
! - for example you can do _list.insert(18, "Part 2:...")
) and finally use ListView.builder
.
Full example:
import 'package:flutter/material.dart';
void main() {
final _list = List<String>.generate(100, (index) => "$index");
_list.insert(0, "Part 1:...");
_list.insert(18, "Part 2:...");
_list.insert(49, "Part 3:...");
final List<ListItem> items = _list.map((value) {
final index = _list.indexOf(value);
if ([0, 18, 49].contains(index)) {
return HeaderItem(value);
} else {
return MessageItem(value);
}
}).toList();
runApp(
MaterialApp(
home: App(items: items),
),
);
}
class App extends StatelessWidget {
final List<ListItem> items;
const App({Key key, this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (item is HeaderItem) {
return Column(
children: <Widget>[
Text(
item.heading,
),
Divider(),
],
);
} else if (item is MessageItem) {
return ListTile(
leading: Text('$index'),
title: Text(
item.title,
style: TextStyle(fontSize: 18),
),
);
}
},
),
);
}
}
abstract class ListItem {}
class HeaderItem implements ListItem {
final String heading;
HeaderItem(this.heading);
}
class MessageItem implements ListItem {
final String title;
MessageItem(this.title);
}
Example with checkboxes:
App
is now StatefulWidget
, MessageItem
has checked
property.
import 'package:flutter/material.dart';
void main() {
final _list = List<String>.generate(100, (index) => "$index");
_list.insert(0, "Part 1:...");
_list.insert(18, "Part 2:...");
_list.insert(49, "Part 3:...");
final List<ListItem> items = _list.map((value) {
final index = _list.indexOf(value);
if ([0, 18, 49].contains(index)) {
return HeaderItem(value);
} else {
return MessageItem(value);
}
}).toList();
runApp(
MaterialApp(
home: App(items: items),
),
);
}
class App extends StatefulWidget {
final List<ListItem> items;
const App({Key key, this.items}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: widget.items.length,
itemBuilder: (context, index) {
final item = widget.items[index];
if (item is HeaderItem) {
return Column(
children: <Widget>[
Text(
item.heading,
),
Divider(),
],
);
} else if (item is MessageItem) {
return ListTile(
leading: Text('$index'),
title: Text(
item.title,
style: TextStyle(fontSize: 18),
),
trailing: Checkbox(
value: item.checked,
onChanged: (value) {
setState(() {
item.checked = value;
});
},
),
);
}
},
),
);
}
}
abstract class ListItem {}
class HeaderItem implements ListItem {
final String heading;
HeaderItem(this.heading);
}
class MessageItem implements ListItem {
final String title;
bool checked = false;
MessageItem(this.title);
}