Flutter:Dart错误:RangeError(索引):无效值:唯一有效值为0:1
大家好,我是 Flutter 新手,正在尝试为电子商务应用程序构建一个变体选择器。我在尝试为 size-color
变化构建尺寸变化小部件时收到此错误。它仅适用于尺寸
或仅颜色
变化。这是错误RangeError (index): Invalid value: Only valid value is 0: 1
。
另外,当我打印数组的长度时,我得到的值是 1。
这个想法是当有人单击没有任何问题地显示的颜色时显示可用的大小。但在尝试显示尺寸时,遇到此错误。
这是 Productcontroller 代码
///size widget
class SelectSizeWidget extends StatefulWidget {
SelectSizeWidget({
Key? key,
}) : super(key: key);
@override
_SelectSizeWidgetState createState() => _SelectSizeWidgetState();
}
class _SelectSizeWidgetState extends State<SelectSizeWidget> {
@override
Widget build(BuildContext context) {
return Consumer<ProductController>(
builder: (_,model,__) {
return Wrap(
spacing: 8,
runSpacing: 8,
children: List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {
if(model.sizeColour.isNotEmpty) {
if(model.selectedColour != null || model.selectedColour != ""){
var _res = model.sizeColour
.where((element) =>
element.var2!.toUpperCase() == model.selectedColour)
.toList();
var _size = _res[index];
return buildSize(_size);
} else {
var _res = model.sizeColour.toList();
var _size = _res[index];
return buildSize(_size);
}
} else if (model.size.isNotEmpty) {
var _size = model.size[index];
return buildSize(_size);
}else if(model.materialSize.isNotEmpty){
var _res = model.materialSize.where((element) =>
element.var1.toUpperCase() == model.selectedMaterial)
.toList();
var _size = _res[index];
return buildSize(_size);
}else{
return SizedBox.shrink();
}
}),
);
}
);
}
SizedBox buildSize(Variant size) {
return SizedBox(
height: 38,
child: RawChip(
label: Text(size.var1),
labelStyle: TextStyle(color: Theme.of(context).hintColor),
padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7),
backgroundColor: Theme.of(context).focusColor.withOpacity(0.05),
selectedColor: Theme.of(context).focusColor.withOpacity(0.2),
selected: size.varId == context.read<ProductController>().selectedVariation,
shape: StadiumBorder(side: BorderSide(color: Theme.of(context).focusColor.withOpacity(0.05))),
onSelected: (bool value) {
context.read<ProductController>().setSize(size.varId);
},
),
);
}
}
- 有关详细
List<Variant> size = [];
List<Variant> colour = [];
List<Variant> sizeColour = [];
List<String> ss = [];
List<String> cc = [];
Future<bool> getProductDetails({required String slug}) async {
final val = await ApiProvider().getProductDetails(slug: slug);
if (val.statusCode == 200 || val.statusCode == 201) {
product = productDetailsResponseFromJson(jsonEncode(val.data));
/// variation
if (product!.variants) {
clearAll();
List<Map<int, Set<String>>> sc = [];
List<String> s = [];
List<String> c = [];
selectedVariation = product!.prdtVari.first.id;
for (var each in product!.prdtVari) {
var _var = each.variation.toLowerCase();
if (_var == 'colour') {
colour.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap));
c.add(each.variationTypes.first.name);
notifyListeners();
} else if (_var == 'size') {
size.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap));
s.add(each.variationTypes.first.name);
notifyListeners();
} else if (_var == 'size-colour') {
sc.add({
each.id: {
each.variationTypes.first.name,
each.variationTypes.last.name
}
});
sizeColour.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap,
var2: each.variationTypes.last.name,
typeMap2: each.variationTypes.last.typeMap));
s.add(each.variationTypes.first.name);
c.add(each.variationTypes.last.name);
notifyListeners();
}
}
ss = s.toSet().toList();
cc = c.toSet().toList();
if(cc.isNotEmpty){
if(product!.prdtVari.first.variation.toLowerCase() == "colour"){
selectedColour = colour.where((element) => element.varId == selectedVariation!).first.var1.toUpperCase();
} else if(product!.prdtVari.first.variation.toLowerCase() == "size-colour") {
selectedColour = sizeColour.where((element) => element.varId == selectedVariation!).first.var2!.toUpperCase();
}
};
notifyListeners();
}
isLoading = false;
notifyListeners();
return true;
} else {
isLoading = false;
notifyListeners();
return false;
}
}
API 模型
// To parse this JSON data, do
//
// final productDetailsResponse = productDetailsResponseFromJson(jsonString);
import 'dart:convert';
ProductDetailsResponse productDetailsResponseFromJson(String str) => ProductDetailsResponse.fromJson(json.decode(str));
String productDetailsResponseToJson(ProductDetailsResponse data) => json.encode(data.toJson());
class ProductDetailsResponse {
ProductDetailsResponse({
required this.category,
required this.title,
required this.variants,
required this.slug,
required this.averageReview,
required this.countReview,
required this.productDetailsInfo,
required this.prdtImg,
required this.prdtVari,
});
int category;
String title;
bool variants;
String slug;
double averageReview;
int countReview;
ProductDetailsInfo productDetailsInfo;
List<ProductDetailsImages> prdtImg;
List<ProductDetailsVariation> prdtVari;
factory ProductDetailsResponse.fromJson(Map<String, dynamic> json) => ProductDetailsResponse(
category: json["category"],
title: json["title"],
variants: json["var"],
slug: json["slug"],
averageReview: json["rating"],
countReview: json["rCount"],
productDetailsInfo: ProductDetailsInfo.fromJson(json["prdtInfo"]),
prdtImg: List<ProductDetailsImages>.from(json["prdtImg"].map((x) => ProductDetailsImages.fromJson(x))),
prdtVari: List<ProductDetailsVariation>.from(json["prdtVari"].map((x) => ProductDetailsVariation.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category": category,
"title": title,
"var": variants,
"slug": slug,
"rating": averageReview,
"rCount": countReview,
"prdtInfo": productDetailsInfo.toJson(),
"prdtImg": List<dynamic>.from(prdtImg.map((x) => x.toJson())),
"prdtVari": List<dynamic>.from(prdtVari.map((x) => x.toJson())),
};
}
class ProductDetailsImages {
ProductDetailsImages({
required this.id,
required this.images,
required this.cover,
});
int id;
String? images;
bool cover;
factory ProductDetailsImages.fromJson(Map<String, dynamic> json) => ProductDetailsImages(
id: json["id"],
images: json["images"],
cover: json["cover"],
);
Map<String, dynamic> toJson() => {
"id": id,
"images": images,
"cover": cover,
};
}
class ProductDetailsInfo {
ProductDetailsInfo({
required this.brand,
required this.mrp,
required this.price,
required this.inStock,
required this.desc,
required this.shipCost,
required this.condition,
});
String? brand;
double mrp;
double price;
String inStock;
String desc;
double? shipCost;
String condition;
factory ProductDetailsInfo.fromJson(Map<String, dynamic> json) => ProductDetailsInfo(
brand: json["brd"],
mrp: json["mrp"],
price: json["price"],
inStock: json["iStock"],
desc: json["desc"],
shipCost: json["shCost"],
condition: json["con"],
);
Map<String, dynamic> toJson() => {
"brand": brand,
"mrp": mrp,
"price": price,
"iStock": inStock,
"desc": desc,
"shCost": shipCost,
"con": condition,
};
}
class ProductDetailsVariation {
ProductDetailsVariation({
required this.id,
required this.variation,
required this.mrp,
required this.price,
required this.inStock,
required this.images,
required this.variationTypes,
});
int id;
String variation;
double mrp;
double price;
String inStock;
List<ProductDetailsImages> images;
List<ProductDetailsVariationType> variationTypes;
factory ProductDetailsVariation.fromJson(Map<String, dynamic> json) => ProductDetailsVariation(
id: json["id"],
variation: json["vAtion"],
mrp: json["mrp"],
price: json["price"],
inStock: json["iStock"],
images: List<ProductDetailsImages>.from(json["imgs"].map((x) => ProductDetailsImages.fromJson(x))),
variationTypes: List<ProductDetailsVariationType>.from(json["vTypes"].map((x) => ProductDetailsVariationType.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"vAtion": variation,
"mrp": mrp,
"price": price,
"iStock": inStock,
"imgs": List<dynamic>.from(images.map((x) => x.toJson())),
"vTypes": List<dynamic>.from(variationTypes.map((x) => x.toJson())),
};
}
class ProductDetailsVariationType {
ProductDetailsVariationType({
required this.id,
required this.name,
required this.typeMap,
});
int id;
String name;
String typeMap;
factory ProductDetailsVariationType.fromJson(Map<String, dynamic> json) => ProductDetailsVariationType(
id: json["id"],
name: json["name"],
typeMap: json["tMap"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"tMap": typeMap,
};
}
谢谢
Hey guys I am new to Flutter and trying to build a variation selector for an eCommerce application. I am getting this error while trying to build a size variation widget for the size-color
variation. It works for size
only or color
only variation. This is the error RangeError (index): Invalid value: Only valid value is 0: 1
.
Also, when I print the length of the array, I am getting the value 1.
The idea is to show the available sizes when someone clicks on a color that gets displayed without any issues. but while trying to show the size, facing this error.
This is the code
///size widget
class SelectSizeWidget extends StatefulWidget {
SelectSizeWidget({
Key? key,
}) : super(key: key);
@override
_SelectSizeWidgetState createState() => _SelectSizeWidgetState();
}
class _SelectSizeWidgetState extends State<SelectSizeWidget> {
@override
Widget build(BuildContext context) {
return Consumer<ProductController>(
builder: (_,model,__) {
return Wrap(
spacing: 8,
runSpacing: 8,
children: List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {
if(model.sizeColour.isNotEmpty) {
if(model.selectedColour != null || model.selectedColour != ""){
var _res = model.sizeColour
.where((element) =>
element.var2!.toUpperCase() == model.selectedColour)
.toList();
var _size = _res[index];
return buildSize(_size);
} else {
var _res = model.sizeColour.toList();
var _size = _res[index];
return buildSize(_size);
}
} else if (model.size.isNotEmpty) {
var _size = model.size[index];
return buildSize(_size);
}else if(model.materialSize.isNotEmpty){
var _res = model.materialSize.where((element) =>
element.var1.toUpperCase() == model.selectedMaterial)
.toList();
var _size = _res[index];
return buildSize(_size);
}else{
return SizedBox.shrink();
}
}),
);
}
);
}
SizedBox buildSize(Variant size) {
return SizedBox(
height: 38,
child: RawChip(
label: Text(size.var1),
labelStyle: TextStyle(color: Theme.of(context).hintColor),
padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7),
backgroundColor: Theme.of(context).focusColor.withOpacity(0.05),
selectedColor: Theme.of(context).focusColor.withOpacity(0.2),
selected: size.varId == context.read<ProductController>().selectedVariation,
shape: StadiumBorder(side: BorderSide(color: Theme.of(context).focusColor.withOpacity(0.05))),
onSelected: (bool value) {
context.read<ProductController>().setSize(size.varId);
},
),
);
}
}
Productcontroller - for detail
List<Variant> size = [];
List<Variant> colour = [];
List<Variant> sizeColour = [];
List<String> ss = [];
List<String> cc = [];
Future<bool> getProductDetails({required String slug}) async {
final val = await ApiProvider().getProductDetails(slug: slug);
if (val.statusCode == 200 || val.statusCode == 201) {
product = productDetailsResponseFromJson(jsonEncode(val.data));
/// variation
if (product!.variants) {
clearAll();
List<Map<int, Set<String>>> sc = [];
List<String> s = [];
List<String> c = [];
selectedVariation = product!.prdtVari.first.id;
for (var each in product!.prdtVari) {
var _var = each.variation.toLowerCase();
if (_var == 'colour') {
colour.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap));
c.add(each.variationTypes.first.name);
notifyListeners();
} else if (_var == 'size') {
size.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap));
s.add(each.variationTypes.first.name);
notifyListeners();
} else if (_var == 'size-colour') {
sc.add({
each.id: {
each.variationTypes.first.name,
each.variationTypes.last.name
}
});
sizeColour.add(Variant(
varId: each.id,
var1: each.variationTypes.first.name,
typeMap1: each.variationTypes.first.typeMap,
var2: each.variationTypes.last.name,
typeMap2: each.variationTypes.last.typeMap));
s.add(each.variationTypes.first.name);
c.add(each.variationTypes.last.name);
notifyListeners();
}
}
ss = s.toSet().toList();
cc = c.toSet().toList();
if(cc.isNotEmpty){
if(product!.prdtVari.first.variation.toLowerCase() == "colour"){
selectedColour = colour.where((element) => element.varId == selectedVariation!).first.var1.toUpperCase();
} else if(product!.prdtVari.first.variation.toLowerCase() == "size-colour") {
selectedColour = sizeColour.where((element) => element.varId == selectedVariation!).first.var2!.toUpperCase();
}
};
notifyListeners();
}
isLoading = false;
notifyListeners();
return true;
} else {
isLoading = false;
notifyListeners();
return false;
}
}
API model
// To parse this JSON data, do
//
// final productDetailsResponse = productDetailsResponseFromJson(jsonString);
import 'dart:convert';
ProductDetailsResponse productDetailsResponseFromJson(String str) => ProductDetailsResponse.fromJson(json.decode(str));
String productDetailsResponseToJson(ProductDetailsResponse data) => json.encode(data.toJson());
class ProductDetailsResponse {
ProductDetailsResponse({
required this.category,
required this.title,
required this.variants,
required this.slug,
required this.averageReview,
required this.countReview,
required this.productDetailsInfo,
required this.prdtImg,
required this.prdtVari,
});
int category;
String title;
bool variants;
String slug;
double averageReview;
int countReview;
ProductDetailsInfo productDetailsInfo;
List<ProductDetailsImages> prdtImg;
List<ProductDetailsVariation> prdtVari;
factory ProductDetailsResponse.fromJson(Map<String, dynamic> json) => ProductDetailsResponse(
category: json["category"],
title: json["title"],
variants: json["var"],
slug: json["slug"],
averageReview: json["rating"],
countReview: json["rCount"],
productDetailsInfo: ProductDetailsInfo.fromJson(json["prdtInfo"]),
prdtImg: List<ProductDetailsImages>.from(json["prdtImg"].map((x) => ProductDetailsImages.fromJson(x))),
prdtVari: List<ProductDetailsVariation>.from(json["prdtVari"].map((x) => ProductDetailsVariation.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"category": category,
"title": title,
"var": variants,
"slug": slug,
"rating": averageReview,
"rCount": countReview,
"prdtInfo": productDetailsInfo.toJson(),
"prdtImg": List<dynamic>.from(prdtImg.map((x) => x.toJson())),
"prdtVari": List<dynamic>.from(prdtVari.map((x) => x.toJson())),
};
}
class ProductDetailsImages {
ProductDetailsImages({
required this.id,
required this.images,
required this.cover,
});
int id;
String? images;
bool cover;
factory ProductDetailsImages.fromJson(Map<String, dynamic> json) => ProductDetailsImages(
id: json["id"],
images: json["images"],
cover: json["cover"],
);
Map<String, dynamic> toJson() => {
"id": id,
"images": images,
"cover": cover,
};
}
class ProductDetailsInfo {
ProductDetailsInfo({
required this.brand,
required this.mrp,
required this.price,
required this.inStock,
required this.desc,
required this.shipCost,
required this.condition,
});
String? brand;
double mrp;
double price;
String inStock;
String desc;
double? shipCost;
String condition;
factory ProductDetailsInfo.fromJson(Map<String, dynamic> json) => ProductDetailsInfo(
brand: json["brd"],
mrp: json["mrp"],
price: json["price"],
inStock: json["iStock"],
desc: json["desc"],
shipCost: json["shCost"],
condition: json["con"],
);
Map<String, dynamic> toJson() => {
"brand": brand,
"mrp": mrp,
"price": price,
"iStock": inStock,
"desc": desc,
"shCost": shipCost,
"con": condition,
};
}
class ProductDetailsVariation {
ProductDetailsVariation({
required this.id,
required this.variation,
required this.mrp,
required this.price,
required this.inStock,
required this.images,
required this.variationTypes,
});
int id;
String variation;
double mrp;
double price;
String inStock;
List<ProductDetailsImages> images;
List<ProductDetailsVariationType> variationTypes;
factory ProductDetailsVariation.fromJson(Map<String, dynamic> json) => ProductDetailsVariation(
id: json["id"],
variation: json["vAtion"],
mrp: json["mrp"],
price: json["price"],
inStock: json["iStock"],
images: List<ProductDetailsImages>.from(json["imgs"].map((x) => ProductDetailsImages.fromJson(x))),
variationTypes: List<ProductDetailsVariationType>.from(json["vTypes"].map((x) => ProductDetailsVariationType.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"vAtion": variation,
"mrp": mrp,
"price": price,
"iStock": inStock,
"imgs": List<dynamic>.from(images.map((x) => x.toJson())),
"vTypes": List<dynamic>.from(variationTypes.map((x) => x.toJson())),
};
}
class ProductDetailsVariationType {
ProductDetailsVariationType({
required this.id,
required this.name,
required this.typeMap,
});
int id;
String name;
String typeMap;
factory ProductDetailsVariationType.fromJson(Map<String, dynamic> json) => ProductDetailsVariationType(
id: json["id"],
name: json["name"],
typeMap: json["tMap"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"tMap": typeMap,
};
}
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
List.generate
正在使用model.ss.length
或model.size.length
来生成您的列表,就像您在这一行中所指示的那样,这意味着 <代码>index <= model.ss.length-1 或
index <= model.size.length-1
。然后你做了所以如果
var _size = _res[index]
抛出RangeError
则意味着_res.length
_res.length
model.ss.length-1
或_res.length < model.size.length-1
但它应该相等,所以解决方案是确保 3 个数组具有相同的长度。List.generate
is usingmodel.ss.length
ormodel.size.length
to generate your list like you instructed on this lineIt means
index <= model.ss.length-1
orindex <= model.size.length-1
. Then you didSo if
var _size = _res[index]
throwRangeError
it means_res.length < model.ss.length-1
or_res.length < model.size.length-1
but it should be equal, so the solution is to make sure the 3 arrays have the same length.尝试用“and”替换“or”,
因为您使用了“or”,如果满足其中一个条件,则它始终为真。因此,即使它是空的,该变量也被分配了空值。
Try replacing the 'or' with 'and'
Since you used or it is always true if either of the condition is met. So even it's empty that variable was assigned with empty value.
当您在列表中渲染数据但没有数据时,经常会发生错误,您尝试在代码中检查 null,因为您没有控制器调用 api 或任何
Error often happen when you render data in list but you hasn't data you try check null in code because you not have controller call api or data any where
我无法阅读所有代码并对其进行测试,但我之前遇到过该错误。什么时候?
例如,
列表中有四个项目,这意味着您的索引将一直到 3,如果您添加的项目多于列表中的项目,则会显示该错误。
我希望我能够解释一下。
I could not read all the code and test it, but I got that error before. When?
for example,
so you have four items in the list which mean your index will be just until 3 if you add more than the items in the list it will show that error.
I hope I was able to explain.