Flutter ListView.Builder() 动态列表 - 显示数据但有错误
Flutter ListView.Builder() dynamic list - shows data but with error
您好,我正在尝试向用户显示新(和旧)版本的应用程序以及更改列表。我创建了一些功能和弹出消息,他们可以在其中查看版本和更改列表。
它有效,但当它显示版本和更改时,它还会显示无限红色字段,并在新版本下出现错误:
RangeError (index): Index out of range: index should be less than 1: 1
旧版本也一样:
RangeError (index): Index out of range: index should be less than 6: 6
我认为 ListView.Builder() 或我发送给它的内容可能有问题。
有人可以帮忙吗?
代码:
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);
}
}
显示新版本的功能
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,
),
]);
}),
),
],
),
],
),
您似乎将 ListView.builder
小部件中的 itemCount:
设置为 _versions.length
。 itemCount
是您的 builder:
函数 运行 的次数。如果itemCount
是7那么builder:
函数会运行7次,每次都会传入一个新的索引,即0,1,2,3,4,5,6 . 这不是问题,但是在您的 builder:
函数中您尝试索引 _listNotSeen
和 _listSeen
。当这些元素少于 _versions
时,就会出现问题。例如,如果 _listNotSeen
有 4 个元素而 _versions
有 7 个元素,那么当索引达到 4 或更高时,您将超出范围。您需要将 _versions.length
替换为与 _listNotSeen
长度相等的内容或您在 builder:
函数中索引的任何内容
您好,我正在尝试向用户显示新(和旧)版本的应用程序以及更改列表。我创建了一些功能和弹出消息,他们可以在其中查看版本和更改列表。
它有效,但当它显示版本和更改时,它还会显示无限红色字段,并在新版本下出现错误:
RangeError (index): Index out of range: index should be less than 1: 1
旧版本也一样:
RangeError (index): Index out of range: index should be less than 6: 6
我认为 ListView.Builder() 或我发送给它的内容可能有问题。 有人可以帮忙吗?
代码:
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);
}
}
显示新版本的功能
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,
),
]);
}),
),
],
),
],
),
您似乎将 ListView.builder
小部件中的 itemCount:
设置为 _versions.length
。 itemCount
是您的 builder:
函数 运行 的次数。如果itemCount
是7那么builder:
函数会运行7次,每次都会传入一个新的索引,即0,1,2,3,4,5,6 . 这不是问题,但是在您的 builder:
函数中您尝试索引 _listNotSeen
和 _listSeen
。当这些元素少于 _versions
时,就会出现问题。例如,如果 _listNotSeen
有 4 个元素而 _versions
有 7 个元素,那么当索引达到 4 或更高时,您将超出范围。您需要将 _versions.length
替换为与 _listNotSeen
长度相等的内容或您在 builder:
函数中索引的任何内容