Hi I'm trying to show new (and old) versions of app with list of changes to users. I created some functions and pop-up message where they can see version and list of changes.
It works but when it shows versions and changes it also shows infinite red field with error under new versions:
RangeError (index): Index out of range: index should be less than 1: 1
And same under older verions:
RangeError (index): Index out of range: index should be less than 6: 6
I think there could be problem with the ListView.Builder() or what I send to it. Can anyone help?
Code:
Future<void> displayNewVersion() async {
List _versions = await readJson(); //geting data from Json
Map<String, bool> _control = await controlSeenVersions(_versions); //sorting what version changes was seen or not
Map<String, List<dynamic>> _listSeen = {}, _listNotSeen = {};
for (var version in _versions) {
if (_control[version["vName"]]) {
_listSeen[version["vName"]] = version["changes"];
} else {
_listNotSeen[version["vName"]] = version["changes"];
}
}
if (_listNotSeen.isNotEmpty) {
showChangelog(_listNotSeen, _listSeen, _versions);
}
}
function to show the new versions
showChangelog(Map<String, List<dynamic>> _listNotSeen, Map<String, List<dynamic>> _listSeen, List _versions) async {
var shortestSide = MediaQuery.of(context).size.shortestSide;
final bool isPhone = shortestSide < 600;
customDialogWithHeaderSE(
context,
isPhone,
LocaleKeys.newVersionTitle + _versions[0]["vName"],
//StatefulBuilder must be here coz you need context and context of dialog itself coz one pop dialog and second navigate..
Container(
margin: const EdgeInsets.all(8.0),
width: 300.0,
child: Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _versions.length,
itemBuilder: (context, int index) {
String key = _listNotSeen.keys.elementAt(index);
return Container(
child: Column(
children: <Widget>[
new ListTile(
title: new Text(key.toString(),
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Container(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: _listNotSeen[key].length,
itemBuilder: (context, int index) {
return Container(
child:
Text("- " + _listNotSeen[key][index]));
}),
)),
new Divider(
height: 2.0,
),
],
));
},
),
),
),
[
if (_listSeen.isNotEmpty)
Column(
children: [
ExpansionTile(
title: Text(
'Older releases',
style: TextStyle(
fontWeight: FontWeight.w400,
color: ColorsApp.blue75_storaenso,
height: 1.5,
fontSize: (isPhone) ? 18.0 : 20.0),
),
children: [
// Change as per your requirement
SizedBox(
height: 300.0, // Change as per your requirement
width: 300.0,
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _versions.length,
itemBuilder: (context, int index) {
String key = _listSeen.keys.elementAt(index);
return Column(children: <Widget>[
new ListTile(
title: new Text(key.toString(), style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Container(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: _listSeen[key].length,
itemBuilder: (context, int index) {
return Container(child: Text("- " + _listSeen[key][index]));
}),
),
),
new Divider(
height: 2.0,
),
]);
}),
),
],
),
],
),
Looks like you set itemCount:
in your ListView.builder
widgets to _versions.length
. itemCount
is how many times your builder:
function will run. If itemCount
is 7 then builder:
function will run 7 times, and each time a new index will be passed in, i.e., 0, 1, 2, 3, 4, 5, 6. This is not a problem, however in your builder:
function you try to index _listNotSeen
and _listSeen
. Issues will arise when these have fewer elements than _versions
. For example, if _listNotSeen
has 4 elements while _versions
has 7 then when the index gets to 4 or higher you will be out of range. You need to replace _versions.length
with something that has equal length to _listNotSeen
or whatever you are indexing in your builder:
function