首页 > 其他分享 >flutter 专题五 Flutter面试之事件分发机制

flutter 专题五 Flutter面试之事件分发机制

时间:2024-11-04 19:44:13浏览次数:5  
标签:分发 HitTestEntry RenderObject 处理事件 Flutter 事件 flutter 节点

一、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

相关文章

  • 【Flutter】 ValueNotifer详解
    在Flutter中,ValueNotifier是一个非常有用的工具,用于管理应用程序中的状态,并且可以轻松地通知UI进行更新。以下是关于ValueNotifier的详细解释和用法:什么是ValueNotifier?ValueNotifier是Flutter中的一个简单的状态管理类,用于持有一个可变的值,并且可以通知侦听器(监听器)当......
  • 极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
    目录前言1.弹性放大按钮效果2.旋转和缩放组合动画3.颜色渐变背景动画4.缩放进出效果前言    在上一篇文章中,我们介绍了Flutter中的隐式动画的一些相关知识,在这篇文章中,我们可以结合多个隐式动画Widget在Flutter中创建一些酷炫的视觉效果,比如弹性按钮、......
  • nextjs 实战开发1 Mercury 二级域名分发系统| 曲速引擎 Warp Drive
    开发目标开发一个免费的二级域名分发系统创建项目root@ubuntu:~/dev-nextjs/mercury_frontend#pnpmcreatenext-app@latest.版本:pnpm-v9.12.2版本:node-vv20.16.0版本:next15.0.2为了开发方便,我们要将脚手架的package.json进行修改,nextdev-H0.0.0.0-p80,这样当我们运......
  • ssh分发密钥脚本
    使用场景->ansible#!/bin/bash#author:kylerock#desc:#1.一键创建秘钥对(如果不存在)#2.一键分发公钥#3.一键检查#1.varskey=/root/.ssh/id_rsaips="73141"pass=1#ips="`cat/server/files/ip.txt`"#2.一键创建秘钥对if[!-f$key];thenssh-k......
  • Flutter go_router库push导航后,浏览器地址栏的地址不更新的问题
    如果你使用.push()方法进行导航后,浏览器的地址栏的地址并没有更新,那是因为go_router经过了一次变更修改行为导致的。配置下边的GoRouter.optionURLReflectsImperativeAPIs=true;代码就行了。也可以去optionURLReflectsImperativeAPIs看属性说明。原文......
  • 在K8S中,有一个公司要向具有各种环境的客户提供所有必需的分发产品的方案,如何看待他们
    在Kubernetes(K8s)环境中,一个公司若要向具有各种环境的客户提供所有必需的分发产品,并希望动态地实现这一关键目标,需要采取一系列精心设计的策略和技术。以下是对他们如何动态地实现这一目标的详细探讨:1.理解客户需求与环境多样性首先,公司需要深入理解不同客户的需求以及他们所处......
  • flutter鸿蒙项目初体验
    flutter鸿蒙项目初体验1.基础的环境变量配置#flutter基础环境配置exportPUB_HOSTED_URL=https://pub.flutter-io.cnexportFLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn#拉取下来的flutter_flutter/bin目录exportPATH=/Users/admin/ohos/flutter_......
  • flutter开发适配鸿蒙之开发环境搭建
    第一:环境搭建1.安装DevEcoStudioNEXTIDE,注意版本应该是Next,当前最新的是Beta3.下载之前需要先登录,后面的模拟器创建还要开发者验证、审核啥的,好在审核进度还可以,我这边提交申请后差不多两个小时审核通过.找到自己电脑系统匹配的版本下载,我的电脑是Window的就选择......
  • Flutter开发鸿蒙,终端一体化
    一.Flutter开发鸿蒙,终端一体化1.flutter鸿蒙一体化介绍Flutter作为一个跨平台的UI框架,其主要目的是让开发者能够用一套代码库来构建iOS、Android以及其他平台(如Web、Windows、macOS等)的应用程序。对于HarmonyOS,虽然它本身不是Flutter的目标平台之一,但由于Flutter的灵活......
  • 【GiraKoo】C++多线程消息分发架构
    【开源需求】C++多线程消息分发架构项目【gi_messager】在多线程环境中,为每个线程提供独立的消息队列MessageLoop。注:主线程默认自动创建消息队列。MessageLoopCenter提供MessageLoop的查询功能。能够获得指定MessageLoop的句柄。同一个MessageLoop可以绑定多个......