概述

#

移除了 MouseTracker 的方法 attachAnnotationdetachAnnotationisAnnotationAttached

背景

#

鼠标事件,例如鼠标指针进入、离开或悬停在某个区域时,是借助在渲染阶段放置在相关区域的 MouseTrackerAnnotation 来检测的。每次更新(新帧或新事件)时,MouseTracker 会比较更新前后鼠标指针悬停的注释,然后相应地分派回调。

管理鼠标指针状态的 MouseTracker 类,曾经要求 MouseRegion 在挂载时附加注释,并在卸载时分离注释。MouseTracker 使用此机制来执行*挂载退出检查*(例如,如果退出是由组件卸载引起的,则不得调用 MouseRegion.onExit),以防止调用未挂载组件的 setState 并抛出异常(详见问题 #44631)。

此机制已被替换为将 MouseRegion 变为一个有状态组件,以便它可以在卸载时通过阻塞回调来自行执行挂载退出检查。因此,这些方法已被移除,并且 MouseTracker 不再跟踪屏幕上的所有注释。

变更说明

#

MouseTracker 类已移除三个与附加注释相关的方法

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

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

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

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

迁移指南

#

MouseTracker.attachAnnotationdetachAnnotation 的调用应被移除,几乎没有影响。

  • MouseRegion 的使用完全不受影响。
  • 如果您的代码直接使用 RenderMouseRegionMouseTrackerAnnotation,请注意,当退出是由以前调用 MouseTracker.detachAnnotation 的事件引起时,现在会调用 onExit。如果没有涉及状态,这应该不是问题;否则,您可能需要添加挂载退出检查,特别是如果回调泄露导致外部组件可能在其内部调用 setState。例如:

迁移前的代码

dart
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); };
  }
}

迁移后的代码

dart
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 的调用。此功能在技术上已不再可能,因为注释不再被跟踪。如果您仍需要此功能,请提交问题。

时间线

#

引入版本: 1.15.4
稳定版本: 1.17

参考资料

#

API 文档

相关 PR