上一回咱们说到RichText是如何实现TextSpanWidgetSpan混排的,这次我们把RichTextTextField合并起来

这是我目前修改的文件,把rich前缀去掉就是原来的名字

.
├── cupertino
│   └── rich_text_selection.dart
├── material
│   └── rich_text_selection.dart
├── rich_editable.dart
├── rich_editable_text.dart
├── rich_text_field.dart
├── rich_text_painter.dart
└── rich_text_selection.dart

首先第一步是将原来的public类名加上Rich前缀,然后全部替换掉。虽然我这里用一句话就带过了,但是真正执行起来还需要小心谨慎,不然什么地方就可能编译不过去了,所以选个顺手的IDE比较重要。

接下来,我们从TextField开始追踪,发现最终执行edit相关逻辑的widget是editable_text.dart中的_Editable,于是我们的修改便从这里开始

这里_Editable继承自LeafRenderObjectWidget,说明现在是不支持子widget的,所以我们把它替换成MultiChildrenRenderObjectWidget,并且收集WidgetSpan的children

editable_text.dart_Editable对应的RenderObject是editable.dart中的RenderEditable,我们把它替换成rich_editable.dart中的RichRenderEditable,然后主要修改RichRenderEditable

现在,我们进入rich_editable.dart中修改RichRenderEditable

原来的RenderEditable是没有ContainerRenderObjectMixinRenderBoxContainerDefaultsMixin的,现在给RichRenderEditable加上

接下来进入layout流程

先来看一下RenderEditableperformLayout()

在这个方法中,大致的流程是:首先对文本进行布局,就是红框中的代码,接下来就是计算当前widget的大小,最后是处理如果输入的文字需要滚动的时候的偏移量。

这段代码中有段注释,翻译过来是:我们在这里获取_textPainter.size,因为下一行给size赋值这行代码将触发我们验证固有大小的方法,这将更改_textPainter的布局,因为固有大小的计算具有破坏性,这意味着如果以后在此方法中使用_textPainter的属性,我们将获得不同的结果。其他_textPainter状态(例如didExceedMaxLines)也将受到影响,尽管我们目前不在这里使用。//参见具有类似问题的RenderParagraph。

说的是先调用final Size textPainterSize = _textPainter.size,是因为size = Size(width, contraints.contrainHeight(_preferredHeight(contraints.maxWidth)))这行代码会触发computeMin/MaxIntrinsicHeight/Widget这一系列方法,这些方法里面可能会重新layout一遍文本,所以之后获取的_textPainter.size的值可能会变化,因此先保存起来

我们把RenderParagraph的layout逻辑复制到RichRenderEditable,如下

红框中的三个方法我们在上篇文章中已经详细阐述过了

接着是paint流程 先看RenderEditablepaint()方法

如果文本需要滚动,则先裁剪部分,然后_paintContents,如果不需要滚动,则直接_paintContents,因此我们去看_paintContents

红框中的内容就是在绘制文本,这里也是我们要替换的地方,替换成下面这个方法,也同样是RenderParagraph中的逻辑

到这里,paint流程就替换完毕了。

接下来,再把computeMin/MaxIntrinsicHeight/Widget这一系列方法的逻辑融合一下就可以了

在这个过程中,我遇到了两个头疼的问题,一个是当RichTextField重绘的时候,有可能会崩溃,是因为没有重新_textPainter.layout引起的,具体的原因不细说了,大家如果有兴趣的话可以看我的源码,里面有个叫rich_text_painter.dart的文件,看了应该就是明白了。另一个问题是TextSpan和WidgetSpan总是重叠在一起,似乎_textPainter.layout在高度方面不起作用一样,这个问题我找了很久,最终发现是在EditableText中设置了一个strutStyle的默认值,这个默认值会固定文本高度。虽然这两个问题被我轻描淡写的几句话带过,但是实际过程中花的时间并不少,文章只是对逻辑融合的大体框架做一个介绍,这种细枝末节的问题就不再赘述了,但是我相信这种问题会随着以后的深入越来越多。

最后,我们来看下效果

我在main.dart中写了这样的代码,代码仅做demo,其中的细节问题请忽略

大体意思是我输入一串字符,然后显示出来,接着后面显示一个小闹钟,接着是一段666666,最后是一个大一点的小图标

在我输入一串“good”之后,显示效果如下:

打开Flutter Inspector看一下边界

目前的效果就是这样,还仅仅是可以显示WidgeSpan,还不能做到输入删除等等操作。我们慢慢来。

接下来,我们来看看如何处理光标的问题

github地址:https://github.com/Fearimdly/rich_text_field

c语言实现英文文本编辑器_用flutter实现富文本编辑器(二)相关推荐

  1. android 富文本框架_五种JavaScript富文本编辑器,总有一款适合你

    全文共2099字,预计学习时长4分钟 也许,你时常会遇到要开发基于Web的文本编辑器的情况.有时候,只需实现一个简约且轻量级的应用程序,不必有其他任何不必要的功能.而有时候,你的首要任务是保护用户的商 ...

  2. 图片 富文本 粘贴_用C++实现富文本控件(中): 撤销

    用C++实现富文本控件: 撤销 本节是关于撤销重做相关实现. 项目地址: Github-RichED 本文备份地址: github 撤销重做 这就被称为UNDO/REDO之类的, 简直是'增量'的代表 ...

  3. 表单如何添加大的文本框_在 Flutter 中进行文本框的创建和设定

    文本框作为一个接收用户输入的组件,被广泛应用于表单构建.即时通讯.搜索等场景中. Flutter 提供了两个开箱即用的文本框组件:TextField 和 TextFormField. 1. 文本框 T ...

  4. mysql数据库存储富文本格式_使用格式将富文本框的数据存储到数据库

    我是wpf的新手,我想将富文本框的数据及其格式(斜体,彩色,粗体..)存储到数据库(Mysql)中.目前,当我保存数据时,格式化将被忽略.此外,当我将其从数据库加载回富文本框时,它会在同一行中显示所有 ...

  5. php去除编辑器html标签,js处理富文本编辑器转义、去除转义、去除HTML标签

    富文本编辑器生成的HTML标签,进行转义,然后写入数据库,防止脚本注入: function htmlEncode(value){ return $(' } 从数据库拿出的转义后的HTML标签内容,先得 ...

  6. java编辑多行文本编辑器_五个最佳编程文本编辑器

    很多场合下我们会用到纯文本编辑器,Windows自带的记事本功能很简陋,因此我们从网友的投票提名中选取了前五个最佳的文本编辑器(实际上有六个).这些编辑器实际上主要适合程序员使用,他们的清单如下. N ...

  7. 【富文本编辑器功能】vue实现富文本编辑器Tinymce功能,保留编辑器格式文章展示在页面上【前后端代码展示,简单好用】

    前言: 这个Tinymce富文本编辑器是vue-element-admin内集成好的,使用过后体验非常不错,很简单易用.这里分享一下,同时又看到了网上帖子都没什么人写前后端同时展示的,很多人想知道编辑 ...

  8. django html文本编辑器,django xadmin 集成DjangoUeditor富文本编辑器

    #### 本文档记录自己的学习历程! #### 介绍 - Ueditor HTML编辑器是百度开源的在线HTML编辑器,功能非常强大 #### 额外功能 - 解决图片视频等无法上传显示问题 #### ...

  9. html JSP 富文本案例,JSP页面引入Ueditor富文本编辑器!

    最近做项目时,需要用到富文本编辑器,使用了百度的Ueditor编辑器,因此 在这和大家分享下 工具/原料 myeclipse,ueditor 方法/步骤 从官网上 地开级还思层似未屏别.域一插式近址发 ...

最新文章

  1. Codespaces
  2. PHP内核之PHP_FUNCTION宏定义
  3. 我在51CTO微职位学软考——网络工程师
  4. 记住,永远不要在MySQL中使用“utf8”-转
  5. 2016.07.17-18 集合方法
  6. POJ - 1061 青蛙的约会(扩展欧几里得)
  7. SVM入门(八)松弛变量(转)
  8. Spring Cloud-鸿鹄Cloud分布式微服务云系统—架构图
  9. POJ 3696 欧拉函数+快速幂
  10. c#正则表达式应用实例
  11. .describe() python_Python实现ARMA模型
  12. 洛谷oj---P1030 求先序排列
  13. endnote快捷标注参考文献
  14. 我看QQ与360之争
  15. 使用GeoGebra绘制三角形的外接圆和内切圆
  16. linux 不识别 svg,manjaro/archlinux用yaourt -Syu滚动升级后大量图标主题不能用svg图标不能识别...
  17. 魅族mx5无法连接远程服务器,魅族mx5手机无法连接电脑怎么办
  18. java eav_entity-framework-4 – 实体框架4和ddd中的EAV
  19. mysql_java.sql.SQLException: null, message from server: Host 'xxx' is not allowed to connect
  20. 消息重放攻击以及预防方法

热门文章

  1. 自由轴法 matlab,一种自由轴法RLC测量电路设计
  2. php中nodethirtythree,node常用模块 - LinearLaw的个人空间 - OSCHINA - 中文开源技术交流社区...
  3. 只会用单片机点灯,很丢人吗?
  4. ubuntu+touch+android,移动操作系统Ubuntu Touch支持安卓应用
  5. reactinput聚焦事件_React focus 事件的坑
  6. python 爬虫框架_Python常用的几个高效率的爬虫框架
  7. 自己帮别人写的网站可以公开源码吗_雷军靠写代码赚第一个 100 万,马化腾亲自写腾讯网,码农出身的大佬...
  8. 牛客假日团队赛5J 护城河 bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 (凸包的周长)...
  9. Linux文件命名规则
  10. 高级软件工程第九次作业:东理三剑客团队作业-随笔4