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

Flutter中Provider函数外访问变量异常:收藏列表刷新后为空

问题原因

当前你的MyAppProvider中selectedItems仅存储在内存里,App重启(包括热重启/刷新)后内存数据会被清空,所以刷新后进入收藏页面会得到空数组。

修复方案

要解决这个问题,需要将收藏数据持久化到本地存储,下面提供两种常用实现方式:

方案一:使用SharedPreferences(适合简单数据结构)

1. 添加依赖

在pubspec.yaml中添加:

dependencies:
  shared_preferences: ^2.2.2

执行flutter pub get安装依赖。

2. 改造Provider类

修改my_provider.dart,添加本地存储的读写逻辑:

import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

class MyAppProvider extends ChangeNotifier {
  List<Items> selectedItems = [];

  MyAppProvider() {
    // 初始化时加载本地存储的收藏数据
    _loadFavorites();
  }

  void addItems(Items items) {
    selectedItems.add(items);
    _saveFavorites(); // 保存到本地
    notifyListeners();
  }

  List<Items> getSelectedItems() {
    return selectedItems;
  }

  // 将收藏列表保存到本地
  Future<void> _saveFavorites() async {
    final prefs = await SharedPreferences.getInstance();
    // 把Items列表转为JSON字符串(需要Items类实现toJson方法)
    final jsonData = jsonEncode(selectedItems.map((item) => item.toJson()).toList());
    await prefs.setString('favorites', jsonData);
  }

  // 从本地加载收藏数据
  Future<void> _loadFavorites() async {
    final prefs = await SharedPreferences.getInstance();
    final savedData = prefs.getString('favorites');
    if (savedData != null) {
      final List<dynamic> jsonList = jsonDecode(savedData);
      selectedItems = jsonList.map((json) => Items.fromJson(json)).toList();
      notifyListeners();
    }
  }
}

3. 给Items类添加JSON序列化方法

确保你的Items类实现toJson和fromJson:

class Items {
  final String id;
  final String name;
  // 其他属性...

  Items({required this.id, required this.name});

  // 转为JSON格式
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      // 其他属性对应添加
    };
  }

  // 从JSON解析为Items对象
  factory Items.fromJson(Map<String, dynamic> json) {
    return Items(
      id: json['id'],
      name: json['name'],
      // 其他属性对应解析
    );
  }
}

方案二:使用Hive(适合复杂数据结构,性能更优)

1. 添加依赖

在pubspec.yaml中添加:

dependencies:
  hive: ^2.2.3
  hive_flutter: ^1.1.0

dev_dependencies:
  build_runner: ^2.4.6

执行flutter pub get安装依赖。

2. 配置Items类并生成适配器

给Items类添加Hive注解,生成适配器:

import 'package:hive/hive.dart';

part 'items.g.dart';

@HiveType(typeId: 0) // 唯一typeId,多个类不能重复
class Items extends HiveObject {
  @HiveField(0)
  final String id;
  @HiveField(1)
  final String name;
  // 其他属性...

  Items({required this.id, required this.name});
}

运行命令生成适配器:

flutter pub run build_runner build

3. 初始化Hive(在main函数中)

import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';

void main() async {
  await Hive.initFlutter();
  Hive.registerAdapter(ItemsAdapter()); // 注册适配器
  await Hive.openBox<Items>('favorites'); // 打开存储收藏的盒子
  runApp(const MyApp());
}

4. 改造Provider类

import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';

class MyAppProvider extends ChangeNotifier {
  late Box<Items> _favoritesBox;
  List<Items> selectedItems = [];

  MyAppProvider() {
    _favoritesBox = Hive.box<Items>('favorites');
    _loadFavorites();
  }

  void addItems(Items items) {
    _favoritesBox.add(items); // 直接存入Hive
    _loadFavorites();
    notifyListeners();
  }

  List<Items> getSelectedItems() {
    return selectedItems;
  }

  void _loadFavorites() {
    selectedItems = _favoritesBox.values.toList();
  }
}
额外代码修正
  1. favorites.dart中Class改为小写class,类名遵循大驼峰命名改为Favorites
  2. 移除listen: false(默认listen: true),这样收藏页面能实时响应Provider的数据变化:
class Favorites extends StatelessWidget {
  const Favorites({super.key});

  @override
  Widget build(BuildContext context) {
    List<Items> favoriteList = Provider.of<MyAppProvider>(context).getSelectedItems();
    print(favoriteList);
    // 示例:用ListView展示收藏内容
    return ListView.builder(
      itemCount: favoriteList.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(favoriteList[index].name),
        );
      },
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:01:08