You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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']),
          );
        },
      ),
    );
  }
}

关键修复点总结

  1. 类型统一:将Provider中_selectedCategory改为String?,和数据中的catagory_id字符串类型匹配。
  2. 修正键名:筛选时使用正确的键名catagory_id,而非拼写错误的category_id。
  3. 生命周期方法修正:将initState移到正确位置,移除不必要的初始化逻辑。
  4. 触发状态更新:点击分类时调用setCategory更新Provider的选中分类ID,确保筛选逻辑生效。
  5. 页面数据获取:商品页面直接从Provider获取筛选后的数据,无需手动传参,保证数据响应式更新。

内容的提问来源于stack exchange,提问作者saba omer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:15:36