闲鱼技术2022年度白皮书-Flutter主题-打造Flutter高性能富文本编辑器—渲染篇(上)

简介: 闲鱼技术2022年度白皮书-Flutter主题-


 

作者:光酒

 

一、 开篇

 

协议篇文章,我们介绍了Flutter富文本编辑器协议层的设计。以Slate为例,介绍了协议层设计的几个重要的概念:嵌套Model、Opeartion、Normalizing;站在Slate的肩膀上,让我们有了一个强壮、设计完善的富文本协议层,接下来就让我们看看渲染层是如何实现的;

 

让我们回顾一下Mural整体的架构设计分层:

 

image.png


渲染层主要工作是将协议Model转换成Widget渲染到屏幕上,以及处理选区、光标的计算和绘制,处理用户的手势交互、键盘交互等一系列工作

 

1. Textfield的渲染实现

 

首先让我们来看下Flutter的TextField是如何渲染的:

 

image.png


如上图所示,Textfield继承自StatefulWidget,会build嵌套的Widget tree,其中有几个比较关键的Widget:

 

TextSelectionGestureDetector处理手势交互相关的逻辑,比如单击移动光标、长按选择文字展示Toolbar等等

 

另一个比较重要的Widget——EditableText;EditableText在build的时候,通过buildTextSpan方法,根据TextEditingValue的普通文本以及composing部分,创建一个Textspan对象给_Editable;最终RenderEditable通过TextPainter将文本绘制到canvas上

 

2. Mural的渲染实现

 

image.png


如上图所示,Mural在渲染层的设计上,与原生TextField前面一部分基本是一致的,不同之处从MuralEditable开始,对应到TextField的EditableText

 

上面在协议层我们说了,Slate在协议在设计上是与Dom一致的,到Flutter渲染层,就会将Dom树转换成Widget tree,最终渲染到屏幕上

 

MuralEditable不再是简单的创建一个TextSpan,而是按照Dom树结构,每一个Element映射成一个Widget;每个Element对应的Widget,创建的RenderObject实现了抽象类:RenderEditorInlineBox

 

image.png


接下来我们再来看看Element对应的Widget,是怎么处理它的子节点的:

 

我们以最简单的EditableTextLine为例,包含Leading和Body两部分,Leading负责渲染段落修饰相关的内容,比如有序段落的序号、引用段落前面的装饰竖线等Body则负责渲染具体的富文本内容,实现了抽象类:RenderEditorTextBox,最终依然将所有的叶子节点转换成InlineSpan,通过TextPainer将文本绘制到屏幕上

 

image.png


EditorUtils的buildChildren方法实现如下:

 

image.png


3. 光标&选区渲染

 

光标和选区是富文本编辑器渲染层另外一个需要处理的难点

 

与原生TextField相比,Mural在处理光标和选区处理更加复杂;TextField所有输入文本都绘制在一个TextPainter,前面我们说过,Mural每个Element都是一个独立的段落,对应一个RenderObject;在Mural中,我们需要计算用户手势操作不同段落的光标位置以及段落之间的选区计算

 

要实现Mural的光标和选区渲染,需要解决如下问题:

 

多Element点击获取TextPosition

TextPosition to MuralPoint

光标位置计算

 

 

1) 多Element点击获取TextPosition

 

image.png


如上图所示,当用户点击绿色光点位置之后,首先我们可以根据点击事件确认被点击是哪一个Element所渲染的RenderObject

 

首先我们通过globalToLocal方法将手势回调的globalPosition转换为相对于Mural的localPosition;接下来遍历MuralRenderEditable的child,寻找包含localPosition的child

 

如上面介绍的,Element渲染的RenderObject实现了RenderEditorInlineBox抽象类,也就可以通过getPositionForOffset方法获取到相对于当前TextPainter的TextPosition

 

2) TextPosition to MuralPoint

 

接下来就要解决第二个问题,如何将TextPosition转换为协议对于光标、选区位置的描述

 

以上图为例,点击之后,TextPosition的Offset为12,而Slate协议是如何描述这样一个光标位置呢?如上图所示,变成了Path为[0,2],offset为2的Point。

 

3) 光标位置计算

 

接下来就是光标位置计算,通过TextPainter的getOffsetForCaret方法,获取选中Element对应RenderObject的光标位置,然后转换成相对于Mural全局的Offset;

 

整体过程梳理如下:

 

image.png


接下篇:https://developer.aliyun.com/article/1225971?groupCode=idlefish

相关文章
|
7月前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
290 0
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
4月前
|
JSON Dart Android开发
Flutter 2024: Impeller引擎引领渲染新纪元
Flutter 2024以Impeller引擎引领渲染新时代,全面提升性能与流畅度。Impeller已在iOS及Android(支持Vulkan/OpenGL)全面部署,Material 3集成深化视觉体验,多视图支持增强复杂UI管理。Dart 3.2与3.4版本迭代优化语言特性与性能,引入宏编程简化JSON处理。桌面与Web端持续优化,深化平台适配。
240 14
|
26天前
|
开发框架 Dart 前端开发
Flutter 是谷歌推出的一款高效跨平台移动应用开发框架,使用 Dart 语言,具备快速开发、跨平台支持、高性能、热重载及美观界面等特点。
Flutter 是谷歌推出的一款高效跨平台移动应用开发框架,使用 Dart 语言,具备快速开发、跨平台支持、高性能、热重载及美观界面等特点。本文从 Flutter 简介、特点、开发环境搭建、应用架构、组件详解、路由管理、状态管理、与原生代码交互、性能优化、应用发布与部署及未来趋势等方面,全面解析 Flutter 技术,助你掌握这一前沿开发工具。
56 8
|
1月前
|
Dart Android开发 开发者
Flutter跨平台开发实战:构建高性能移动应用
【10月更文挑战第25天】随着移动设备种类的增加,开发者面临跨平台应用开发的挑战。Flutter作为Google推出的开源UI工具包,凭借其强大的跨平台能力和高效的开发效率,成为解决这一问题的新方案。本文将介绍Flutter的核心优势、实战技巧及性能优化方法,通过一个简单的待办事项列表应用示例,帮助读者快速上手Flutter,构建高性能的移动应用。
42 0
|
4月前
|
SQL 分布式计算 大数据
Flutter技术实践问题之Flutter应用过程中的基础建设如何解决
Flutter技术实践问题之Flutter应用过程中的基础建设如何解决
34 10
|
4月前
|
新零售 前端开发 小程序
Flutter技术实践问题之基于Flutter的Canvas的应用优势如何解决
Flutter技术实践问题之基于Flutter的Canvas的应用优势如何解决
41 2
|
4月前
|
Web App开发 新零售 前端开发
Flutter技术实践问题之阿里集团内Flutter体系化建设如何解决
Flutter技术实践问题之阿里集团内Flutter体系化建设如何解决
47 1
|
4月前
|
缓存
Flutter Image从网络加载图片刷新、强制重新渲染
Flutter Image从网络加载图片刷新、强制重新渲染
146 1
|
4月前
|
Kubernetes Cloud Native 搜索推荐
探索云原生技术:Kubernetes入门与实践打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第31天】云原生技术正改变着应用开发和部署的方式。本文将带你了解云原生的基石——Kubernetes,通过实际的代码示例,从安装到部署一个简单的应用,让你迅速掌握Kubernetes的核心概念和操作方法。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你进入云原生世界的桥梁。
|
5月前
|
Dart JavaScript Java
flutter 架构、渲染原理、家族
flutter 架构、渲染原理、家族
97 3
下一篇
DataWorks