Flutter 最小颗粒化控制是否刷新:GetBuilder 过渡到 GetShouldRebuild

312 阅读1分钟

背景:

实现最小颗粒化的刷新,减少没必要的 rebuild

业务使用场景:

  1. 首先来看看正常的GetBuilder的构造方法
GetBuilder<T extends GetxController>(builder: (logic) {

});

说明:GetxController 实现类,只要调用了 update(), 那么所有的 GetBuilder 关联的 GetxController 类都会被刷新到,但有的时候,我们只是需要刷新关联数据的,所以这个就需要缓存 widget 只在满足条件下的时候才刷新 widget

  1. 添加条件判断代码
/// 改造伪代码
GetBuilder<T extends GetxController>(builder: (logic) {
    return Container();
}, shouldRebuild: (GetxController oldCtl, GetxController newCtl) {
/// 如果新的GetxController 不等于老的GetxController 那就执行更新操作。
    return newCtl != oldCtl;
});

ps: 有了上面的业务背景,和条件判断的伪代码,那我们就可以编写真正的代码了

封装实现:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

/// 构建一个是否刷新的判断条件函数
typedef GetShouldRebuildFunction<T> = bool Function(T oldController, T newController);

/// 是否需要rebuild
class GetShouldRebuild<T extends GetxController> extends StatefulWidget {
/// 沿用GetBuilder的builder 构建widget
  final GetControllerBuilder<T> builder;
  
  final GetShouldRebuildFunction<T>? shouldRebuild;
  
  const GetShouldRebuild({Key? key, required this.builder, this.shouldRebuild}) : super(key: key);
  
  @override
  _GetShouldRebuildState<T> createState() => _GetShouldRebuildState<T>();
}

class _GetShouldRebuildState<T extends GetxController> extends State<GetShouldRebuild<T>> {
/// 缓存的widget
  Widget? oldWidget;
  
/// 记录刷新之后的Controller
  T? oldController;

  @override
  Widget build(BuildContext context) {
    return GetBuilder<T>(builder: (T newController) {
    /// 1. 没有缓存的widget,就创建一个
    /// 2. 没有使用调用shouldRebuild,就每次都调用builder
    /// 3. 根据shouldRebuild 返回的条件决定是否调用builder更新widget,否则使用缓存的widget
      if (oldWidget == null ||
          (widget.shouldRebuild == null ? true : widget.shouldRebuild!(oldController!, newController))) {
        final T controller = newController;
        final Widget newWidget = widget.builder(newController);
        oldController = controller;
        oldWidget = newWidget;
      }
      return oldWidget!;
    });
  }
}

业务落实使用:

真正的关联条件代码,跟 GetBuilder 一样的构建方式,只不过多了一个 shouldRebuild

GetShouldRebuild<TenlantsGrowthLogic>(builder: (newCtl) {
/// 根据新的 GetxController 来构建widget
  return Container();
}, shouldRebuild: (oldCtl, newCtl) {
/// 判断新老 GetxController 是否相同
  return oldCtl != newCtl;
});