Flutter组件如何检测外部异步预约列表更新及加载完成状态?
解决方案
核心思路
让数据管理类具备状态通知能力,同时保证全局实例唯一,让组件自动感知数据变化并更新,无需手动调用setState,也不用把数据逻辑放到组件内部。
1. 改造预约列表管理类
将AppointmentList改为单例并继承ChangeNotifier,添加加载状态标记,每次数据更新或状态变化时通知监听者:
import 'package:flutter/foundation.dart'; class AppointmentList extends ChangeNotifier { // 单例模式,确保全局只有一个实例 static final AppointmentList _instance = AppointmentList._internal(); factory AppointmentList() => _instance; AppointmentList._internal(); List<Map<String, String>> appointments = []; bool isLoading = true; // 标记是否仍在加载数据 Future init(int range) async { isLoading = true; notifyListeners(); // 通知组件加载开始 for (int i = 0; i < range; i++) { // 替换为实际的HTTP GET请求逻辑 await Future.delayed(const Duration(seconds: 1)); // 模拟每秒加载一条数据 appointments.add({"Name": "预约${i+1}"}); notifyListeners(); // 每次新增数据后通知组件更新 } isLoading = false; notifyListeners(); // 通知组件加载完成 } }
2. 修正主方法初始化逻辑
确保初始化的是全局单例实例:
Future main() async { // 启动时触发数据加载,无需包裹额外函数 AppointmentList().init(30); }
3. 改造Flutter组件
使用AnimatedBuilder监听AppointmentList的状态变化,自动重建UI,无需手动调用setState:
import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; class AppointmentOverviewContainer extends StatefulWidget { const AppointmentOverviewContainer({super.key}); @override State<AppointmentOverviewContainer> createState() => _AppointmentOverviewContainerState(); } class _AppointmentOverviewContainerState extends State<AppointmentOverviewContainer> { // 获取全局唯一的预约列表实例 final AppointmentList _appointmentList = AppointmentList(); @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _appointmentList, builder: (context, child) { // 根据数据状态展示不同内容 if (_appointmentList.appointments.isNotEmpty) { return FittedBox( fit: BoxFit.scaleDown, child: Text( _appointmentList.appointments[0]['Name'] ?? '', style: GoogleFonts.lato(fontSize: 20, fontWeight: FontWeight.w500), ), ); } else if (!_appointmentList.isLoading) { // 加载完成但无数据的情况 return FittedBox( fit: BoxFit.scaleDown, child: Text( '暂无预约数据', style: GoogleFonts.lato(fontSize: 20, fontWeight: FontWeight.w500), ), ); } else { // 正在加载中的状态 return FittedBox( fit: BoxFit.scaleDown, child: Text( 'Loading Appointments', style: GoogleFonts.lato(fontSize: 20, fontWeight: FontWeight.w500), ), ); } }, ); } }
关键说明
- 单例模式:保证
main中初始化的实例和组件中使用的是同一个,数据能实时同步。 - ChangeNotifier:提供轻量级的状态通知机制,每次数据或加载状态变化时调用
notifyListeners(),触发UI更新。 - AnimatedBuilder:依赖
Listenable(ChangeNotifier实现了该接口)自动重建UI,完全符合“无法使用setState”的限制。 - 加载状态标记:通过
isLoading变量可以明确判断数据是否全部加载完成,区分“加载中”和“加载完成无数据”两种状态。
内容的提问来源于stack exchange,提问作者ThrillerGriller
相关产品推荐
相关产品推荐

