Flutter:Dart错误:RangeError(索引):无效值:唯一有效值为0:1

发布于 2025-01-10 17:50:17 字数 10508 浏览 0 评论 0原文

大家好,我是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

水晶透心 2025-01-17 17:50:17

List.generate 正在使用 model.ss.lengthmodel.size.length 来生成您的列表,就像您在这一行中所指示的那样,

List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {

这意味着 <代码>index <= model.ss.length-1 或index <= model.size.length-1。然后你做了

var _res = model.sizeColour.where((element) => element.var2!.toUpperCase() == model.selectedColour).toList();

所以如果 var _size = _res[index] 抛出 RangeError 则意味着 _res.length _res.length model.ss.length-1_res.length < model.size.length-1 但它应该相等,所以解决方案是确保 3 个数组具有相同的长度。

List.generate is using model.ss.length or model.size.length to generate your list like you instructed on this line

List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {

It means index <= model.ss.length-1 or index <= model.size.length-1. Then you did

var _res = model.sizeColour.where((element) => element.var2!.toUpperCase() == model.selectedColour).toList();

So if var _size = _res[index] throw RangeError 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.

迷途知返 2025-01-17 17:50:17

尝试用“and”替换“or”,

if(model.selectedColour != null && model.selectedColour != "")

因为您使用了“or”,如果满足其中一个条件,则它始终为真。因此,即使它是空的,该变量也被分配了空值。

Try replacing the 'or' with 'and'

if(model.selectedColour != null && model.selectedColour != "")

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.

情独悲 2025-01-17 17:50:17

当您在列表中渲染数据但没有数据时,经常会发生错误,您尝试在代码中检查 null,因为您没有控制器调用 api 或任何

  • 可以检查行代码是否有“if”的数据...
  • 检查列表长度 > > 0
  • "var _size = _res[索引];"也许索引为空

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

  • you can check line code has "if" ...
  • check length of list > 0
  • "var _size = _res[index];" maybe index null
弃爱 2025-01-17 17:50:17

我无法阅读所有代码并对其进行测试,但我之前遇到过该错误。什么时候?
例如,

    List<String> myList = [1 , 2 ,3 ,4];

child : ListView(
children: [
  Text("${mylist[0]}"),
  Text("${mylist[1]}"),
  Text("${mylist[2]}"),
  Text("${mylist[3]}"),
  Text("${mylist[4]}"),
]
) ;

列表中有四个项目,这意味着您的索引将一直到 3,如果您添加的项目多于列表中的项目,则会显示该错误。
我希望我能够解释一下。

I could not read all the code and test it, but I got that error before. When?
for example,

    List<String> myList = [1 , 2 ,3 ,4];

child : ListView(
children: [
  Text("${mylist[0]}"),
  Text("${mylist[1]}"),
  Text("${mylist[2]}"),
  Text("${mylist[3]}"),
  Text("${mylist[4]}"),
]
) ;

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文