c语言实现英文文本编辑器_用flutter实现富文本编辑器(二)
上一回咱們說到RichText是如何實現TextSpan和WidgetSpan混排的,這次我們把RichText和TextField合并起來
這是我目前修改的文件,把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是沒有ContainerRenderObjectMixin和RenderBoxContainerDefaultsMixin的,現在給RichRenderEditable加上
接下來進入layout流程
先來看一下RenderEditable的performLayout()
在這個方法中,大致的流程是:首先對文本進行布局,就是紅框中的代碼,接下來就是計算當前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流程 先看RenderEditable的paint()方法
如果文本需要滾動,則先裁剪部分,然后_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实现富文本编辑器(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 国内最大原料药龙头股
- 下一篇: shell 数组里追加数值_shell编