Rich text editor
Considering that rich text editing needs to support long text types, most rich texts cannot reuse Views using custom single Edittext. Therefore, the rich text editor implemented based on RecycleView is currently in the process of development.
For the implementation of rich text editors, we will definitely think of several necessary features that the implemented editor needs to support:
1. It involves display and editing of a large number of text, pictures, and text styles.
2. Involves extremely complex user interactions.
The rich text editor I know on Github is basically implemented based on two types:
Here are some personal opinions on these two solutions.
First of all, one disadvantage of the rendering performance of WebView is. Secondly, when it involves extremely complex human-computer interactions, it will be more difficult to implement WebView. Another point is that the compatibility of WebView is also a point that needs to be considered.
For rewriting a single EditText, it is indeed very scalable for interaction, text rendering, and style support. However, considering that there will be a large number of pictures, the memory situation needs to be taken into account here. For EditText, there is definitely no View reuse. Basically, as much memory as there are pictures, it requires. On the other hand, native TextView has always been criticized for rendering a large amount of text, and there are many solutions for optimization of the performance of TextView.
So I ended up choosing to use RecyclerView as an implementation solution for implementing a rich text editor. Although there are pitfalls, it is also a feasible solution. (Douban's editor is implemented using RecyclerView)
Advantages : First of all, RecyclerVie, as a native component, has very good performance for the display of a large number of UI components. Secondly, the RecyclerView's multiplexing mechanism provides good support for the control of memory consumption.
Disadvantages:: Of course, this is not the first choice for implementing rich text editors. I have encountered many big pitfalls in the implementation process. Here are a few:
1. Focus control
2. Data splicing
3. Style storage
4. The position of the cursor
and much more...
Fortunately, the solution was found in the end, so I will share this implementation solution here, and provide an implementation solution for people in need.
1. Bold, italic, underline, midscore, strikethrough, hyperlink, reference style, H1, H2, H3, H4 of the text.
2. Insert and delete pictures
3. Select text to change style in real time
4. Keep the style in line wrapping anywhere.
5. Delete two lines into one line to maintain style.
6. Display text styles in real time with the cursor to the control panel.
7. Insert styles at any position
8. The final edit text is transferred to MarkDown (there are bugs~...)
wait. . .
For the RecyclerView implementation, the corresponding operation of carriage return is to add a Model, so carriage return line wrapping and deletion requires a lot of logical processing, and also involves the splicing and segmentation of style indexes. In short, it is a big pit.
After selecting, you need to index the cursor, style, clear and split the style, and recreate and assign the style. Big pit, big pit.
When the cursor corresponds to the string of the corresponding style, the panel below changes the current style in real time. It is necessary to use the logical judgment of the interval to make logical judgments on the cursor and style intervals, and there are more and more pitfalls. . .
There are also many complex interactive processing, which is not displayed here. You can check the source code for details.
RichEditor
The project is not published to JitPack here, because as a rich text editor, everyone has their own unique needs and interaction methods, and there is no way to achieve a rich text that can meet all needs. And since the interaction logic of rich text editors is indeed complex, it is impossible to ensure compatibility with all interactions and situations, so here we just do our best to implement the interaction situation.
1. Introduce editor's lib to project 2.xml to add editor
<com.study.xuan.editor.widget.Editor
android:id="@+id/editor"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
It will be used normally.
It is so simple that it is encapsulated and used to use RichHelper
//绑定xml中的Editor
public void attach(Editor editor);
//new 一个Editor
public Editor buildEditor(Context context)
//部分事件回调
public void setCallBack(onEditorEventListener callBack)
//操作面板右侧空白增加自定义布局
public void setMoreOperateLayout(View view)
//异步转义MarkDown
public void toMarkDown()
public interface onEditorCallback {
//行数量变化时
void onLineNumChange(List<RichModel> data);
//点击操作面板的图片添加图片,可以使用自己项目中的图片框架,选中后对应调用editor.addPhoto(List<String> data);方法即可
void onPhotoEvent();
//转义MarkDown的进度回调
void onMarkDownTaskDoing(int progress, int max);
//转义MarkDown成功
void onMarkDownTaskFinished(String markdown);
}
Global singleton, the underlying architecture, helps to implement the overall functions of RichEditor.
The implementation class PanelBuilder contains two implementation classes. FontParamBuilder represents the style of character type and ParagraphBuilder represents the style of paragraph type. The communication method between Panle and Editor is through the IPanel in the underlying RichBuilder singleton.
Abstract engineering class, used to create span types in outer layer. Among them, abstract factories are divided into three span factories: ICharacterStyleFactory, IParagraphFactory, and IUpdateAppearanceFactory, which correspond to CharacterFactory (character style span factory), ParagraphFactory (paragraph style factory), and (custom factory not implemented).
Search strategy is used to traverse and process span styles in a certain paragraph. NormalSearch implements ISearchStrategy and uses regular traversal processing (can customize fast sorting or other efficient sorting methods for processing)
Parameter management interface, implements the ParamManager corresponding to the class, which is used to compare and process the current style and pre-input style.
Editor implementation class, inherited from RecyclerView, Adapter corresponds to RichAdapter, and Model corresponds to RichModel.
Input filter for style processing when input and deletion.
SpanStep1Filter
The first-level filter is used to handle the processing of SPAN_EXCLUSIVE_INCLUSIVE and SPAN_EXCLUSIVE_EXCLUSIVE when handling style appends and confusions.
SpanStep2Filter
The second-level filter is used to handle the creation and maintenance of styles, to obtain all style sets of the current text, and to record the corresponding index of the style, and to maintain it in the corresponding RichModel.
Asynchronous processing, used to process the conversion of data to the corresponding conversion type.
Parse
Converting interface
MarkDownParse
Logical processing converted to MarkDown syntax, using regular expressions.
Data processing class, using data processing related to merge styles, processing styles, etc.
Panel represents the operation panel, and Panel uses EditorPanelAlpha by default. Panel is implemented through IPanel in RichBuilder to link the editor.
[2018.3.17]: Rich text editing within a line of text.
[2018.3.19]: Complete the deletion of multiple lines of text, add one line, and delete the next line to the previous line. And keep style.
[2018.3.20]: Complete the deletion and addition of multiple lines of text, including the first line of deletion and the in-line input, keeping the rich text style moving with the paragraph.
[2018.3.24]: Complete synchronization of the operation bar after clicking, keeping the current text style and operation bar style unified.
[2018.3.29]: Complete the function of inserting new styles and initially complete the basic functions of editing.
[2018.4.09]: Complete paragraph style function.
[2018.4.11]: Preliminary completion of MarkDown syntax escape.
Copyright 2017 [DrownCoder]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.