MouseTracker 不再附加注解
概述
#移除了 MouseTracker
的 attachAnnotation
、detachAnnotation
和 isAnnotationAttached
方法。
背景
#鼠标事件,例如鼠标指针进入、退出或悬停在某个区域时,是通过放置在感兴趣区域的 MouseTrackerAnnotation
在渲染阶段检测到的。在每次更新(新帧或新事件)时,MouseTracker
会比较更新前后鼠标指针悬停的注解,然后相应地分派回调。
MouseTracker
类负责管理鼠标指针的状态,过去需要 MouseRegion
在挂载时附加注解,在卸载时分离注解。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) {/* ... */}
}
RenderMouseRegion
和 MouseTrackerAnnotation
不再执行挂载-退出检查,而 MouseRegion
仍然执行。
迁移指南
#调用 MouseTracker.attachAnnotation
和 detachAnnotation
应被移除,影响很小或没有影响。
- 使用
MouseRegion
的地方应该完全不受影响。 - 如果您的代码直接使用了
RenderMouseRegion
或MouseTrackerAnnotation
,请注意,当退出是由以前调用MouseTracker.detachAnnotation
的事件引起时,现在会调用onExit
。如果没有涉及状态,这不应该有问题,否则您可能需要添加挂载-退出检查,特别是当回调泄漏时,外部 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
- MouseTracker 不再需要附加注解,这促成了此次更改。
- 改进 MouseTracker 生命周期:将检查移至帧后,该 issue 首先引入了挂载-退出更改,详情请参阅onExit 的更改。