一、Flutter中事件分发的主要类及以及它们之间的关系
1.1 主要的类
PointerEvent、HitTestResult、HitTestEntry、RenderObject
1.2 PointerEvent
PointerEvent是Flutter中所有事件的基类。它包含了事件的类型、位置、时间戳、设备信息等。PointerEvent的子类包括PointerDownEvent、PointerMoveEvent、PointerUpEvent等。
1.3. HitTestResult
HitTestResult是事件分发的结果,它记录了事件分发过程中的一些信息。HitTestResult中有一个_hitTestEntries私有变量,它是一个List类型,用来存储事件分发的过程(即HitTestEntry)。
1.4 . HitTestEntry
HitTestEntry记录了事件分发的过程,它包含了一个RenderObject和一个BoxHitTestResult。RenderObject表示事件分发过程中当前节点对应的渲染对象,而BoxHitTestResult则包含了这个节点的位置信息。
1.5 . RenderObject
RenderObject是Flutter中渲染树节点的基类,它包含了节点的位置、大小、绘制等信息。每个widget都对应一个RenderObject,在渲染时会被转换为对应的RenderObject。
二、他们之间的分发流程
2.1 事件的生成
事件的生成通常由系统底层完成,例如点击屏幕或者滑动鼠标等。当系统检测到事件时,会将事件封装成PointerEvent对象,并传递给Flutter引擎。
2.2 事件的传递
Flutter引擎收到事件后,会将事件传递给根节点对应的RenderObject,即PipelineOwner。PipelineOwner会创建一个HitTestResult对象,用来记录事件分发的结果。
2.3 事件的分发
在PipelineOwner中,会调用_renderView.hitTest方法,将事件分发给渲染树中的节点。hitTest方法的实现如下:
void hitTest(HitTestResult result, Offset position) {
assert(attached);
final HitTestEntry entry = HitTestEntry(this);
result.add(entry);
if (hitTestChildren(result, position)) {
handleEvent(entry);
}
}
在这个方法中,首先创建了一个HitTestEntry对象,将其添加到HitTestResult中记录分发结果。然后调用hitTestChildren方法,将事件继续向下传递。如果事件被处理了,则调用handleEvent方法处理事件。hitTestChildren方法的实现如下:
bool hitTestChildren(HitTestResult result, Offset position) {
RenderObject child = lastChild;
while (child != null) {
final bool hit = child.hitTest(result, position: position);
if (hit)
return true;
child = childBefore(child);
}
return false;
}
在这个方法中,先遍历当前节点的所有子节点,调用它们的hitTest方法,将事件向下传递。如果子节点中有处理事件的节点,则返回true,否则返回false。
2.4 事件的处理
当事件到达目标节点时,会调用该节点的handleEvent方法来处理事件。handleEvent方法的实现因节点类型而异,例如GestureDetector会调用onTap、onDoubleTap等回调函数来处理事件,而RenderBox则会调用handleEventForBox方法来处理事件。
handleEventForBox方法的实现如下:
void handleEventForBox(HitTestEntry entry, PointerEvent event) {
bool absorbed = hitTestSelf();
if (!absorbed && size.contains(event.localPosition)) {
handleEvent(entry, event);
absorbed = true;
}
if (!absorbed)
absorbPointer(event);
}
在这个方法中,首先调用hitTestSelf方法来判断节点是否可以处理事件。如果节点不能处理事件,则调用absorbPointer方法将事件标记为已处理。如果节点可以处理事件,则调用handleEvent方法来处理事件,并将事件标记为已处理。
2.5 事件的冒泡
当事件处理完成后,会将事件向上传递,直到到达根节点。这个过程与事件的分发类似,只不过是从当前节点的父节点开始向上传递。
在整个事件分发的过程中,每个RenderObject都会创建一个HitTestEntry对象,将其添加到HitTestResult中记录分发结果。在最终处理事件时,Flutter会遍历HitTestResult中的HitTestEntry对象,依次调用每个RenderObject的事件处理回调函数。
标签:分发,HitTestEntry,RenderObject,处理事件,Flutter,事件,flutter,节点 From: https://blog.csdn.net/m0_61164038/article/details/143491566