概述

#

移除了 MouseTrackerattachAnnotationdetachAnnotationisAnnotationAttached 方法。

背景

#

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

MouseTracker 类负责管理鼠标指针的状态,过去需要 MouseRegion 在挂载时附加注解,在卸载时分离注解。MouseTracker 使用此功能执行挂载-退出检查(例如,如果退出是由 widget 卸载引起的,则不得调用 MouseRegion.onExit),以防止调用已卸载 widget 的 setState 并抛出异常(在 Issue #44631 中有详细说明)。

该机制已被替换,现在 MouseRegion 是一个有状态的 widget,因此它可以自行执行挂载-退出检查,通过在卸载时阻止回调来完成。因此,这些方法已被移除,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。如果没有涉及状态,这不应该有问题,否则您可能需要添加挂载-退出检查,特别是当回调泄漏时,外部 widget 可能会在其中调用 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 的调用。该功能在技术上不再可能,因为注解不再被跟踪。如果您以某种方式需要此功能,请提交一个 issue。

时间线

#

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

参考资料

#

API 文档

相关 PR