当前位置: 首页 > news >正文

flutter 局部刷新控件Selector源码实现原理

Flutter 中的 Selector 组件是 provider 包提供的一个优化工具,用于在状态管理中仅选择所需数据片段,避免不必要的 Widget 重建。其实现原理基于以下几个关键点:


1. 核心设计目标

  • 选择性重建:仅当特定数据变化时触发 Widget 重建,而非整个状态对象变化时都重建。

  • 性能优化:通过比较数据片段的前后值,避免无关数据变化导致的冗余重建。


2. 实现原理

a. 继承自 StatefulWidget

Selector 是 StatefulWidget,其状态类(如 _SelectorState)负责管理数据监听和重建逻辑。

class Selector<T, R> extends StatefulWidget {
  final R Function(BuildContext, T) selector;
  final Widget Function(BuildContext, R, Widget?) builder;
  final Widget? child;

  const Selector({ /* 参数初始化 */ });
  
  @override
  _SelectorState<T, R> createState() => _SelectorState<T, R>();
}
b. 状态管理(State)
  • 监听数据变化:通过 Provider.of<T>(context) 获取依赖的状态对象,并监听其变化。

  • 缓存上一次值:保存上一次 selector 函数的结果(_lastValue)。

  • 比较新旧值:在数据变化时,重新计算 selector 结果,并与旧值比较,决定是否重建。

class _SelectorState<T, R> extends State<Selector<T, R>> {
  R? _lastValue;
  Widget? _child;

  @override
  void didChangeDependencies() {
    final T model = Provider.of<T>(context);
    final R newValue = widget.selector(context, model);

    // 比较新旧值,决定是否重建
    if (_shouldUpdate(newValue)) {
      setState(() => _lastValue = newValue);
    }
    super.didChangeDependencies();
  }

  bool _shouldUpdate(R newValue) {
    return widget.shouldRebuild?.call(_lastValue, newValue) 
        ?? (newValue != _lastValue);
  }

  @override
  Widget build(BuildContext context) {
    return widget.builder(context, _lastValue as R, _child);
  }
}
c. 生命周期方法
  • didChangeDependencies:在依赖的 Provider 数据变化时触发,重新计算并比较 selector 结果。

  • setState:仅当数据变化时调用,触发 Widget 重建。


3. 关键机制

a. 选择性监听
  • 使用 selector 函数从状态对象中提取关心的数据片段。例如:

    selector: (context, model) => model.name,
  • 仅当 selector 返回值变化时,才触发 builder 执行。

b. 值比较策略
  • 默认比较:使用 != 操作符比较新旧值(依赖对象覆写 == 和 hashCode)。

  • 自定义比较:通过 shouldRebuild 参数提供自定义逻辑,应对复杂数据结构的比较。

    Selector<Model, String>(
      shouldRebuild: (prev, next) => prev.length != next.length,
      // ...
    )
c. 子组件优化(Child Propagation)
  • child 参数:传递静态子组件,避免其随 Selector 重建。在 builder 中复用:

    builder: (context, value, child) {
      return Column(
        children: [Text(value), child!],
      );
    },
    child: const ExpensiveWidget(),

4. 性能优化点

  • 最小化重建范围:仅重建依赖特定数据片段的 Widget。

  • 避免闭包陷阱:将 selector 和 builder 定义为顶层或静态方法,防止不必要的重建。

  • 不可变数据:确保 selector 返回值是不可变的,或正确实现 == 和 hashCode


5. 源码实现总结

  1. 监听依赖:通过 Provider.of 监听状态对象变化。

  2. 提取数据:调用 selector 函数获取关心的数据片段。

  3. 比较值:若新值不同或满足 shouldRebuild 条件,触发重建。

  4. 构建 UI:调用 builder 函数生成 Widget,传递缓存子组件。

通过这一机制,Selector 在复杂的状态管理中显著提升性能,避免不必要的 UI 更新。

相关文章:

  • Spring之Bean的生命周期过程中调用的方法
  • MySQL -操作
  • 12个大语言模型平台对比测试-搜索视角
  • 网络安全(黑客技术)一2025年自学入门手册_合天网安-零基础系统学习网络安全教程下载
  • 使用MATLAB结合EasySpin进行ESR模拟的详细步骤及示例代码
  • 达梦数据库授权给某个用户查询其他指定用户下所有表的权限
  • OSPF BIT 类型说明
  • labview中VISA串口出现异常的解决方案
  • 基于element-ui封装月日选择器(不包含年)
  • Vue.js响应式基础
  • 设计模式 简单汇总
  • DeepSeek引发的全栈开发范式革命?
  • 复用时钟 重映射(Remap)
  • DeepSeek 助力 Vue3 开发:打造丝滑的页眉(Header)
  • C++ Qt常见面试题(4):Qt事件过滤器
  • RIP-AV:使用上下文感知网络进行视网膜动脉/静脉分割的联合代表性实例预训练
  • docker-compose方式启动Kafka Sasl加密认证(无zk)
  • “AI安全与治理:构建可信赖的人工智能生态系统”论坛将亮相CES Asia 2025
  • 【QT问题】Ubantu环境下解决已经下载好的qt怎么添加或卸载其他组件
  • OpenCV计算摄影学(7)HDR成像之多帧图像对齐的类cv::AlignMTB
  • 广州营销网站建设/百度河南代理商
  • 工作期间员工花钱做的网站/百度公司
  • flashfxp 网站/网上怎么推广产品
  • 付费阅读网站建设/南京seo收费
  • 潍坊地区做幼儿园网站的/手机优化器
  • 三合一网站有必要吗/网站策划报告