• Flutter 实现dispose探测控件



    前言

    开发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探测控件。

  • 相关阅读:
    Pyhton专项进阶——http协议、cookie、session和认证-1
    std::exception的使用,c++异常
    【Java-----IO流(五)之数据流详解】
    ​LeetCode解法汇总LCP 50. 宝石补给
    【编程题】【Scratch四级】2021.03 程序优化
    Frida
    string 类以及模拟实现
    layui talbe内容自动换行以及固定列自适应换行后的高度
    R语言中的数据重塑
    Yolov8-pose关键点检测:模型轻量化创新 | ​BiLevelRoutingAttention 动态稀疏注意力 | CVPR2023 BiFormer
  • 原文地址:https://blog.csdn.net/u013113678/article/details/139575454