如何在Flutter中使用Provider获取并筛选数据
Flutter分类筛选商品问题修复方案
核心问题分析
你的代码存在以下几个关键错误导致筛选功能失效:
- 类型不匹配:Provider中
_selectedCategory是int类型,但数据里的catagory_id是字符串类型(如'1'),直接对比会不匹配。 - 键名拼写错误:筛选时用了
e['category_id'],但实际数据里的键是catagory_id(少了一个t)。 - 生命周期方法位置错误:
initState被写在build方法内部,导致语法错误且无法正确执行。 - 未触发Provider状态更新:点击分类时没有调用
setCategory更新选中的分类ID,导致筛选逻辑不生效。 - 初始值逻辑错误:
_selectedCategory初始值为0,getOnlineItem中判断_selectedCategory == null永远为假,无法返回全部商品。
分步修复代码
1. 修复Provider类
import 'package:flutter/material.dart'; class OnlineShopingProvider with ChangeNotifier { // 改为String?类型,和数据中的catagory_id类型一致,初始值设为null表示未筛选 String? _selectedCategory; final dynamic _data = [ { 'catagory_id': '1', 'catagory_name': 'shoe', 'catagory_img': 'https://thumbs.dreamstime.com/b/gadgets-accessories-gadgets-accessories-isolated-white-background-133429004.jpg', }, { 'catagory_id': '2', 'catagory_name': 'clothes', 'catagory_img': 'https://www.freevector.com/uploads/vector/preview/1761/FreeVector-Womens-Clothes-Silhouettes.jpg', }, ]; final dynamic _item = [ { 'item_name': 'addidass', 'item_img': 'https://thumbs.dreamstime.com/b/gadgets-accessories-gadgets-accessories-isolated-white-background-133429004.jpg', 'price': '4000', 'catagory_id': '1', 'item_description': " is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries," }, { 'item_name': 'nike', 'item_img': 'https://thumbs.dreamstime.com/b/gadgets-accessories-gadgets-accessories-isolated-white-background-133429004.jpg', 'price': '3000', 'catagory_id': '1', 'item_description': " is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries," }, { 'item_name': 'reebok', 'item_img': 'https://thumbs.dreamstime.com/b/gadgets-accessories-gadgets-accessories-isolated-white-background-133429004.jpg', 'price': '2000', 'catagory_id': '1', 'item_description': " is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries," }, { 'item_name': 'chanel', 'item_img': 'https://thumbs.dreamstime.com/b/gadgets-accessories-gadgets-accessories-isolated-white-background-133429004.jpg', 'price': '2000', 'catagory_id': '2', 'item_description': " is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries," }, { 'item_name': 'CUCCI', 'item_img': 'https://thumbs.dreamstime.com/b/gadgets-accessories-gadgets-accessories-isolated-white-background-133429004.jpg', 'price': '2000', 'catagory_id': '2', 'item_description': " is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries," }, ]; List cart = []; get datalist => _data; get items => _item; List getOnlineItem() { // 修复判断逻辑,同时修正键名拼写错误 if (_selectedCategory == null) { return _item; } else { return _item.where((e) => e['catagory_id'] == _selectedCategory).toList(); } } void setCategory(String? id) { _selectedCategory = id; notifyListeners(); } }
2. 修复分类组件CatagoriesCard
import 'package:flutter/material.dart'; import 'package:onlineshoping1/Assets/colors.dart'; import 'package:onlineshoping1/screans/item.dart'; import 'package:provider/provider.dart'; import '../provider/provider.dart'; class CatagoriesCard extends StatefulWidget { final dynamic listt; // 添加required标记参数 const CatagoriesCard({required this.listt, Key? key}) : super(key: key); @override State<CatagoriesCard> createState() => _CatagoriesCardState(); } class _CatagoriesCardState extends State<CatagoriesCard> { // 把initState移到build方法外面,作为类的生命周期方法 @override void initState() { super.initState(); // 移除不必要的初始化逻辑,点击时才需要处理筛选 } void setCategory(String catagoryId) { OnlineShopingProvider provider = Provider.of(context, listen: false); provider.setCategory(catagoryId); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { // 先调用setCategory更新Provider状态 setCategory(widget.listt['catagory_id']); // 跳转到商品页面,无需传参,直接从Provider获取筛选后的数据 Navigator.push( context, MaterialPageRoute(builder: (context) => const Item()), ); }, child: Container( width: double.infinity, height: 110, margin: const EdgeInsets.only(top: 20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: const [ BoxShadow( color: Colors.grey, blurRadius: 5, offset: Offset(0, 5), ) ]), child: Padding( padding: const EdgeInsets.all(8.0), child: Row( children: [ Container( height: 110, width: 110, margin: const EdgeInsets.only(right: 20), decoration: BoxDecoration( color: tdgrey, borderRadius: BorderRadius.circular(10), ), child: Image.network(widget.listt['catagory_img']), ), Text( widget.listt['catagory_name'], style: const TextStyle(fontSize: 15), ), ], ), )), ); } }
3. 商品页面Item示例(补充代码)
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../provider/provider.dart'; class Item extends StatelessWidget { const Item({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 获取Provider中筛选后的商品数据 final provider = Provider.of<OnlineShopingProvider>(context); final filteredItems = provider.getOnlineItem(); return Scaffold( appBar: AppBar(title: const Text('商品列表')), body: ListView.builder( itemCount: filteredItems.length, itemBuilder: (context, index) { final item = filteredItems[index]; return ListTile( title: Text(item['item_name']), subtitle: Text('价格: ${item['price']}'), leading: Image.network(item['item_img']), ); }, ), ); } }
关键修复点总结
- 类型统一:将Provider中
_selectedCategory改为String?,和数据中的catagory_id字符串类型匹配。 - 修正键名:筛选时使用正确的键名
catagory_id,而非拼写错误的category_id。 - 生命周期方法修正:将
initState移到正确位置,移除不必要的初始化逻辑。 - 触发状态更新:点击分类时调用
setCategory更新Provider的选中分类ID,确保筛选逻辑生效。 - 页面数据获取:商品页面直接从Provider获取筛选后的数据,无需手动传参,保证数据响应式更新。
内容的提问来源于stack exchange,提问作者saba omer
相关产品推荐
相关产品推荐

