如何实时获取SharedPreferences中Notifications列表长度并更新UI?
SharedPreferences本身没有内置的监听机制,你原来的Future函数只能单次获取数据,无法感知后续变化。下面提供两种实用方案实现实时更新UI:
方案一:用ChangeNotifier(结合provider包)
这是Flutter中最常用的状态管理方式之一,核心是把通知列表的状态托管到可监听对象中,修改数据时主动通知UI刷新。
- 先添加依赖到
pubspec.yaml:
dependencies: flutter: sdk: flutter provider: ^6.0.5 shared_preferences: ^2.2.2
- 创建通知状态管理类:
import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; class NotificationProvider extends ChangeNotifier { List<Notifications> _notifications = []; // 对外暴露只读的列表和数量 List<Notifications> get notifications => _notifications; int get notificationCount => _notifications.length; // 初始化时从SharedPreferences加载数据 Future<void> loadNotifications() async { final prefs = await SharedPreferences.getInstance(); final notificationsString = prefs.getString('notifications'); if (notificationsString != null) { _notifications = (jsonDecode(notificationsString) as List) .map((e) => Notifications.fromJson(e)) .toList(); notifyListeners(); } } // 添加通知(示例操作,可根据需求修改) Future<void> addNotification(Notifications notification) async { _notifications.add(notification); await _saveToPrefs(); notifyListeners(); } // 删除通知(示例操作) Future<void> removeNotification(int index) async { _notifications.removeAt(index); await _saveToPrefs(); notifyListeners(); } // 私有方法:将列表保存到SharedPreferences Future<void> _saveToPrefs() async { final prefs = await SharedPreferences.getInstance(); final notificationsString = jsonEncode( _notifications.map((e) => e.toJson()).toList(), ); await prefs.setString('notifications', notificationsString); } }
- 在UI中使用:
首先在main.dart里注册Provider:
void main() { runApp( ChangeNotifierProvider( create: (context) => NotificationProvider()..loadNotifications(), child: const MyApp(), ), ); }
然后在需要显示数量的页面监听状态:
Consumer<NotificationProvider>( builder: (context, provider, child) { return Text('通知数量:${provider.notificationCount}'); }, )
每次调用addNotification或removeNotification时,会自动同步更新SharedPreferences并通知UI刷新,实现实时更新。
方案二:使用StreamController
如果不想引入状态管理包,也可以用Stream实现监听:
- 创建Stream管理类:
import 'dart:async'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; class NotificationStream { final _countController = StreamController<int>.broadcast(); Stream<int> get countStream => _countController.stream; // 初始化加载并发送初始数量 Future<void> init() async { final count = await _getNotificationCount(); _countController.add(count); } // 修改通知列表后调用此方法,发送新数量 Future<void> updateCount() async { final count = await _getNotificationCount(); _countController.add(count); } // 私有方法:获取当前通知数量 Future<int> _getNotificationCount() async { final prefs = await SharedPreferences.getInstance(); final notificationsString = prefs.getString('notifications'); if (notificationsString == null) return 0; final notifications = (jsonDecode(notificationsString) as List) .map((e) => Notifications.fromJson(e)) .toList(); return notifications.length; } // 记得关闭控制器避免内存泄漏 void dispose() { _countController.close(); } }
- 在UI中监听Stream:
class NotificationPage extends StatefulWidget { const NotificationPage({super.key}); @override State<NotificationPage> createState() => _NotificationPageState(); } class _NotificationPageState extends State<NotificationPage> { final NotificationStream _notificationStream = NotificationStream(); @override void initState() { super.initState(); _notificationStream.init(); } @override void dispose() { _notificationStream.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return StreamBuilder<int>( stream: _notificationStream.countStream, initialData: 0, builder: (context, snapshot) { return Text('通知数量:${snapshot.data}'); }, ); } }
每次修改SharedPreferences里的通知列表后,调用_notificationStream.updateCount(),StreamBuilder就会收到新数量并自动更新UI。
核心逻辑说明
不管用哪种方案,关键都是在修改通知列表的时机主动触发更新——因为SharedPreferences本身不会主动通知数据变化,必须由我们在添加/删除操作后,同步更新状态并告知UI。
内容的提问来源于stack exchange,提问作者user8
相关产品推荐
相关产品推荐

