文章目录
- 前言
- 一、什么是dispose探测控件?
- 1、通常情况
- 2、使用dispose探测控件
- 二、如何实现
- 1、继承StatefulWidget
- 2、定义dipose回调
- 3、定义child
- 4、重载Dispose方法
- 5、build child
- 三、完整代码
- 四、使用示例
- 1、基本用法
- 2、设置定义数据
- 总结
前言
开发flutter一般会用状态管理工具,用了状态管理后大部分控件都会是StatelessWidget,StatefulWidget有dispose重载获取控件销毁时机,但StatelessWidget则没有,此时我们要获取控件销毁的时机就需要另寻他法了。
一、什么是dispose探测控件?
这是一个控件用于帮助探测无状态控件的销毁时机,有点类似visibility_detector用于探测控件的显示和隐藏。
1、通常情况
通常情况下想要知道一个页面是否销毁或切换了,需要通过StatefulWidget的dispose方法获取。代码如下:
class Page extends StatefulWidget {
const Page({
super.key,
});
_Page createState() => _Page();
}
class _Page<T extends Widget, S> extends State<Page> {
void dispose() {
super.dispose();
//此处获取到dispose时机
}
void didUpdateWidget(covariant Page oldWidget) {
super.didUpdateWidget(oldWidget);
//此处获取到控价刷新时机
}
Widget build(BuildContext context) {
return const SizedBox();
}
}
2、使用dispose探测控件
在使用使用状态管理的情况下,通常都是StatelessWidget页面,将其改成StatefulWidget,分成两个类显然是麻烦的。如果有了DisposeDetector(dispose探测控件),作为一个控件放入StatelessWidget页面中,就可以直接获取到dispose时机了。
class Page2 extends StatelessWidget {
const Page2({
super.key,
});
Widget build(BuildContext context) {
return DisposeDetector(
child: const SizedBox(),
onDispose: () {
//此处获取到dispose时机
},
onDidUpdateWidget: (DisposeDetector<SizedBox, dynamic> oldWidget) {
//此处获取到控价刷新时机
},
);
}
}
二、如何实现
1、继承StatefulWidget
2、定义dipose回调
3、定义child
4、重载Dispose方法
5、build child
三、完整代码
dispose_detector.dart
import 'package:flutter/material.dart';
/// 创建人: xin
/// 创建时间: 2023/6/15 13:44
/// 注释: 销毁探测控件
class DisposeDetector<T extends Widget, S> extends StatefulWidget {
final Function onDispose;
final Function(DisposeDetector<T, S> oldWidget) onDidUpdateWidget;
final T child;
final S? tag; //自定义数据
const DisposeDetector({super.key,
required this.child,
required this.onDispose,
required this.onDidUpdateWidget,
this.tag,
});
_DisposeDetector<T, S> createState() => _DisposeDetector<T, S>();
}
class _DisposeDetector<T extends Widget, S> extends State<DisposeDetector<T, S>>
with TickerProviderStateMixin {
void dispose() {
super.dispose();
widget.onDispose();
}
void didUpdateWidget(covariant DisposeDetector<T, S> oldWidget) {
super.didUpdateWidget(oldWidget);
widget.onDidUpdateWidget(oldWidget);
}
Widget build(BuildContext context) {
return widget.child;
}
}
四、使用示例
1、基本用法
class Page2 extends StatelessWidget {
const Page2({
super.key,
});
Widget build(BuildContext context) {
return DisposeDetector(
child: const SizedBox(),
onDispose: () {
//此处获取到dispose时机
},
onDidUpdateWidget: (DisposeDetector<SizedBox, dynamic> oldWidget) {
//此处获取到控价刷新时机
},
);
}
}
2、设置定义数据
class Page2Controller {
void dispose() {
//销毁逻辑
}
}
class Page2 extends StatelessWidget {
final _ctrl = Page2Controller();
Page2({
super.key,
});
Widget build(BuildContext context) {
return DisposeDetector(
tag: _ctrl, //自定义数据,记录当前的controller
onDispose: () {
//此处获取到dispose时机
_ctrl.dispose();
},
onDidUpdateWidget:
(DisposeDetector<SizedBox, Page2Controller> oldWidget) {
//此处获取到控价刷新时机
if (oldWidget.tag != _ctrl)
//如果刷新控件时controller改变了,则销毁旧controller
{
oldWidget.tag!.dispose();
}
},
child: const SizedBox(),
);
}
}
总结
以上就是今天要讲的内容,本文提供的控件是比较有用的,尤其是业务逻辑有数据释放的需求,比如播放器之类的,控件销毁后需要结束播放,将播放资源销毁,如果是用StatelessWidget则没办法实现,用StatefulWidget又会使得页面实现变得麻烦或者复杂,最好的方法则是使用本文提供的dispose探测控件。