Flutter Riverpod 2.0:如何通过onDispose回调释放TabController?
正确释放Riverpod Notifier中TabController资源的实现方式
核心实现要点
- 用
autoDispose标记Provider,让Notifier在不再被监听时自动触发销毁 - 重写Notifier内置的
dispose方法(而非自定义onDispose)来释放TabController资源 - 严格遵循不可变状态更新规则,不能直接修改
state的属性,必须通过copyWith生成新实例
修正后的完整代码
EntryController(保持原定义即可)
class EntryController { final TabController? tabController; final List<DictionaryEntry> history; EntryController({ required this.history, this.tabController, }); EntryController copyWith({ TabController? tabController, List<DictionaryEntry>? history, }) { return EntryController( history: history ?? this.history, tabController: tabController ?? this.tabController, ); } }
ExpandedEntryController(关键修改部分)
@riverpod class ExpandedEntryController extends _$ExpandedEntryController { // 开启自动销毁逻辑 @override bool get autoDispose => true; @override EntryController build() { return EntryController( history: [], ); } void updateState(EntryController controller) => state = controller; void seeRelatedWord(DictionaryEntry relatedWord) { // 不可直接修改原history列表,必须生成新列表+新状态实例 final newHistory = List<DictionaryEntry>.from(state.history)..add(relatedWord); state = state.copyWith(history: newHistory); // 空安全处理,避免TabController未初始化时崩溃 state.tabController?.animateTo(0); } // 重写dispose方法,在Notifier销毁时释放TabController @override void dispose() { state.tabController?.dispose(); super.dispose(); } }
额外说明
autoDispose生效后,当最后一个监听该Provider的组件被销毁时,Notifier会自动调用dispose方法- 原代码中直接
state.history.add(relatedWord)属于修改不可变类的内部状态,会导致Riverpod无法感知状态变化,UI不会同步更新 - 使用
?.替代!做空安全处理,避免TabController未初始化时触发空指针异常
内容的提问来源于stack exchange,提问作者José Carlos
相关产品推荐
相关产品推荐

