Flutter使用Provider遇RangeError及类型转换问题求助
问题:RangeError (index): Invalid value: Not in inclusive range 0..5: 12 错误排查
正在编写第一个Provider类,尝试从列表中获取商品名称。此前遇到_internallinkedhashmap<string, dynamic>错误,添加.cast<String, dynamic>()后,现在出现RangeError,询问是否与列表长度有关。
ItemProperties组件代码
import 'package:ecnomic/provider/provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/container.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:provider/provider.dart'; import '../service/colors.dart'; class ItemProperties extends StatefulWidget { const ItemProperties({super.key}); @override State<ItemProperties> createState() => _ItemPropertiesState(); } class _ItemPropertiesState extends State<ItemProperties> { @override Widget build(BuildContext context) { List items = []; final itemprovider = Provider.of<onlineShopingProvider>(context, listen: false); items = itemprovider.getOnlineItem; return Container( color: Colors.blue, height: 500, width: double.infinity, child: GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 5, // mainAxisSpacing: 10, // childAspectRatio: 3 / 2, ), itemCount: 20, itemBuilder: ((context, index) { return Column( children: [ Image.network( 'https://hips.hearstapps.com/hmg-prod/images/2020-bmw-750i-xdrive-252-1566180109.jpg?crop=1.00xw:0.927xh;0,0.0366xh&resize=2048:*'), Text('$index'), Text( '${itemprovider.getOnlineItem[index].item_name.cast<String, dynamic>()}), ], ); }))); } }
Provider类代码
import 'package:flutter/material.dart'; class onlineShopingProvider with ChangeNotifier { final dynamic _onlineitem = [ { "item_id": 2, "item_name": "Jeep Wrangler Sahara", "item_price": "80000", "item_image": "https://www.motortrend.com/uploads/sites/11/2020/01/2020-Jeep-Wrangler-Unlimited-Sahara-4x4-25958.jpg?fit=around%7C875:492", "category_id": 22, "category_name": "Jeep", "item_color": "#FF0000" }, { "item_id": 2, "item_name": "Jeep Wrangler Sahara", "item_price": "80000", "item_image": "https://www.motortrend.com/uploads/sites/11/2020/01/2020-Jeep-Wrangler-Unlimited-Sahara-4x4-25958.jpg?fit=around%7C875:492", "category_id": 22, "category_name": "Jeep", "item_color": "#FF0000" }, { "item_id": 18, "item_name": "Jeep Grand Cherokee Summit", "item_price": "80000", "item_image": "https://hips.hearstapps.com/hmg-prod/images/2023-jeep-grand-cherokee-summit-4x4-101-1667328305.jpeg?crop=0.617xw:0.520xh;0.353xw,0.451xh&resize=2048:*", "category_id": 22, "category_name": "Jeep", "item_color": "#FF0000" }, { "item_id": 3, "item_name": "BMW X5", "item_price": "100000", "item_image": "https://www.motortrend.com/uploads/2022/11/2023-BMW-X5-xDrive40i-front-three-quarter-view-11.jpg?fit=around%7C875:492.1875", "category_id": 23, "category_name": "BMW", "item_color": "#000000" }, { "item_id": 4, "item_name": "BMW 7 Series", "item_price": "100000", "item_image": "https://hips.hearstapps.com/hmg-prod/images/2020-bmw-750i-xdrive-252-1566180109.jpg?crop=1.00xw:0.927xh;0,0.0366xh&resize=2048:*", "category_id": 23, "category_name": "BMW", "item_color": "#000000" }, { "item_id": 4, "item_name": "BMW 8 Series", "item_price": "107000", "item_image": "https://www.caranddriver.com/photos/g27011971/2020-bmw-7-series-drive-gallery/", "category_id": 23, "category_name": "BMW", "item_color": "#000000" } ]; final dynamic shopingCatagory = [ { "category_id": 22, "category_name": "Jeep", "category_image": "https://pngimg.com/uploads/jeep/jeep_PNG95.png" }, { "category_id": 24, "category_name": "Toyota", "category_image": "https://www.freepnglogos.com/uploads/toyota-logo-png/toyota-logos-brands-logotypes-0.png" }, { "category_id": 23, "category_name": "BMW", "category_image": "https://pngimg.com/uploads/bmw_logo/bmw_logo_PNG19714.png" } ]; get getOnlineItem => _onlineitem; get getShopingCatagory => shopingCatagory; }
错误截图

解决方案
1. RangeError的直接原因
是的,这个错误完全和列表长度有关。你的_onlineitem列表只有6个元素(索引范围0-5),但GridView.builder的itemCount设为20,当索引走到12时,超出了列表的最大有效索引5,触发数组越界错误。
2. 核心修复步骤
- 修正itemCount:将
itemCount: 20改为itemCount: items.length,确保GridView仅渲染列表中实际存在的元素,避免越界。 - 移除多余的cast并修正取值方式:
item_name是Map中的字符串值,无需.cast<String, dynamic>(),之前的_internallinkedhashmap错误是因为错误使用了对象属性访问符.item_name,正确的Map取值应该用[]语法,比如items[index]['item_name']。
修正后的ItemProperties关键代码片段
GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 5, ), itemCount: items.length, // 使用列表实际长度作为itemCount itemBuilder: ((context, index) { return Column( children: [ // 可以直接使用列表中存储的图片链接 Image.network(items[index]['item_image']), Text('$index'), // 正确的Map取值方式 Text(items[index]['item_name']), ], ); }))
额外优化建议
- 指定列表类型:将Provider中的
final dynamic _onlineitem改为final List<Map<String, dynamic>> _onlineitem,通过静态类型检查提前发现潜在的类型错误。 - 使用Consumer简化状态监听:如果需要监听Provider数据变化,使用
Consumer<onlineShopingProvider>替代Provider.of,代码更简洁且能避免不必要的Widget重建。
内容的提问来源于stack exchange,提问作者saba omer
相关产品推荐
相关产品推荐

