Flutter显示CircularProgressIndicator后setState调用异常解决方案咨询
解决方案
问题本质
你当前使用的fbgetLessons方法返回的是Stream<QuerySnapshot>类型的异步数据流,原有代码用同步逻辑调用getLessons时,不等流返回数据就直接返回了空的listOfLessons,所以即便立即调用setState也不会加载到有效数据。
改造步骤
你不需要自己封装LessonsSpeaker类,直接将Firebase返回的原生流转换为业务需要的List<Lesson>类型流即可,逻辑更简洁也不容易出错。
1. 改造getLessons方法
将返回值改为Stream<List<Lesson>>,直接通过map方法转换流数据:
Stream<List<Lesson>> getLessons() { FirebaseLessonRepository lessonRepository = FirebaseLessonRepository(); return lessonRepository.fbgetLessons().map((collectionSnapshot) { List<Lesson> listOfLessons = []; collectionSnapshot.docs.forEach((documentSnapshot) { FbLesson fbLesson = FbLesson.fromSnapshot(documentSnapshot); List<DateTime> classOfferings = []; fbLesson.classOfferings!.forEach((fbClassOffering) { classOfferings.add( DateTime.fromMillisecondsSinceEpoch( fbClassOffering.seconds * 1000)); }); Lesson lesson = Lesson(); lesson.lessonCode = fbLesson.lessonCode; lesson.prerequisite = fbLesson.prerequisite; lesson.description = fbLesson.description; lesson.online = fbLesson.online; lesson.sequence = fbLesson.sequence; lesson.classOfferings = classOfferings; listOfLessons.add(lesson); }); return listOfLessons; }); }
2. 在State类中监听流数据
首先在State中声明流订阅变量用于后续取消监听,避免内存泄漏:
StreamSubscription? _lessonSubscription; List<Lesson> _listOfLessons = [];
修改initState逻辑,监听流数据更新后再调用setState刷新页面:
@override void initState() { super.initState(); _lessonSubscription = lessonController.getLessons().listen((lessonList) { setState(() { _listOfLessons = lessonList; }); }); }
重写dispose方法取消订阅:
@override void dispose() { _lessonSubscription?.cancel(); super.dispose(); }
3. 原有build逻辑保持不变
你原有的_listOfLessons.length == 28判断逻辑无需修改,流首次返回数据时会自动触发页面刷新,满足条件就会切换到正常页面,后续Firebase数据更新也会自动同步刷新。
内容的提问来源于stack exchange,提问作者SpeedyVV
相关产品推荐
相关产品推荐

