MouseTracker 不再附加注释

概述

MouseTracker 的方法 attachAnnotationdetachAnnotationisAnnotationAttached 已被移除。

上下文

在渲染阶段,通过在感兴趣区域上放置 MouseTrackerAnnotation 可以检测鼠标事件,例如鼠标指针进入、退出或悬停在区域上。每次更新(一个新的帧或事件)时, MouseTracker 会比较更新前后鼠标指针悬停的注释,然后执行相应的回调。

MouseTracker 类管理鼠标指针的状态,要求 MouseRegion 在挂载(mounted)时附加注释,在移除(unmounted)时分离注释。MouseTracker 使用它来执行 挂载退出检查。(例如,如果是因移除 widget 引起的退出,则不调用 MouseRegion.onExit),防止移除 widget 时调用 setState 引发的异常(详情可见 Issue #44631)。

这种机制已经被 MouseRegion 变为一个有状态的 widget 所取代,它可以通过在卸载时阻止回调来自行执行挂载退出检查。因此,这些方法已被删除,MouseTracker 不再跟踪屏幕上的所有注释。

更改描述

MouseTracker 类删除了三个与附加注释相关的方法:

 class MouseTracker extends ChangeNotifier {
   // ...
-  void attachAnnotation(MouseTrackerAnnotation annotation) {/* ... */}

-  void detachAnnotation(MouseTrackerAnnotation annotation) {/* ... */}

-  @visibleForTesting
-  bool isAnnotationAttached(MouseTrackerAnnotation annotation) {/* ... */}
 }

RenderMouseRegionMouseTrackerAnnotation 不再执行挂载退出检查,在 MouseRegion 中仍然执行。

迁移指南

删除 MouseTracker.attachAnnotationdetachAnnotation 的调用,这几乎没有影响:

  • MouseRegion 的使用应该完全不受影响。

  • 如果你的代码直接使用 RenderMouseRegionMouseTrackerAnnotation,请注意现在 onExit 的回调会在 MouseTracker.detachAnnotation 事件引起的退出时触发。如果不涉及任何状态,应该不会有问题,否则你可能希望添加挂载的退出检查,尤其是在回调泄漏时,以便外部 widget 可以调用 setState。例如:

迁移前的代码:

class MyMouseRegion extends SingleChildRenderObjectWidget {
  const MyMouseRegion({this.onHoverChange});

  final ValueChanged<bool> onHoverChange;

  @override
  RenderMouseRegion createRenderObject(BuildContext context) {
    return RenderMouseRegion(
      onEnter: (_) { onHoverChange(true); },
      onExit: (_) { onHoverChange(false); },
    );
  }

  @override
  void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
    renderObject
      ..onEnter = (_) { onHoverChange(true); }
      ..onExit = (_) { onHoverChange(false); };
  }
}

迁移后的代码:

class MyMouseRegion extends SingleChildRenderObjectWidget {
  const MyMouseRegion({this.onHoverChange});

  final ValueChanged<bool> onHoverChange;

  @override
  RenderMouseRegion createRenderObject(BuildContext context) {
    return RenderMouseRegion(
      onEnter: (_) { onHoverChange(true); },
      onExit: (_) { onHoverChange(false); },
    );
  }

  @override
  void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
    renderObject
      ..onEnter = (_) { onHoverChange(true); }
      ..onExit = (_) { onHoverChange(false); };
  }

  @override
  void didUnmountRenderObject(RenderMouseRegion renderObject) {
    renderObject
      ..onExit = onHoverChange == null ? null : (_) {};
  }
}

必须删除 MouseTracker.isAnnotationAttached 的调用。由于注释不再被跟踪,因此该功能在技术上不再可行。如果你需要此功能,请提交 issue。

时间轴

发布于版本:1.15.4
发布于稳定版本:1.17

参考文献

API 文档:

相关 PR: