博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
富文本编辑器 - RichEditor
阅读量:5166 次
发布时间:2019-06-13

本文共 4408 字,大约阅读时间需要 14 分钟。

基本功能

RichEditor 是一个继承自 WebView 的自己定义 view,枚举类型 Type 定了它所支持的排版格式:

public enum Type {  BOLD,  ITALIC,  SUBSCRIPT,  SUPERSCRIPT,  STRIKETHROUGH,  UNDERLINE,  H1,  H2,  H3,  H4,  H5,  H6}

首先在构造函数中载入一个 html 文件。

private static final String SETUP_HTML = "file:///android_asset/editor.html"public RichEditor(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  setVerticalScrollBarEnabled(false);  setHorizontalScrollBarEnabled(false);  getSettings().setJavaScriptEnabled(true);  setWebChromeClient(new WebChromeClient());  setWebViewClient(createWebviewClient());  // 载入 html 文件  loadUrl(SETUP_HTML);  applyAttributes(context, attrs);}

当中 html 文件 - editor.html 载入了两个 css 文件 - normalize.css & style.css。一个 js 文件 - rich_editor.js

body 中插入了一个 contentEditable="true"div

      

rich_editor.js 中定义了非常多排版功能的 API,RichEditor 相似 proxy。对外提供了 Java API。

public void setEditorFontColor(int color) {  String hex = convertHexColorString(color);  exec("javascript:RE.setBaseTextColor('" + hex + "');");}

当中 exec 用于运行 js 代码。

protected void exec(final String trigger) {  if (isReady) {    load(trigger);  } else {    postDelayed(new Runnable() {      @Override public void run() {        exec(trigger);      }, 100);    }  }}

仅仅有当 rich_editor.html 载入完毕后 isReady 才会被置为 true

protected class EditorWebViewClient extends WebViewClient {
@Override public void onPageFinished(WebView view, String url) { isReady = url.equalsIgnoreCase(SETUP_HTML); if (mLoadListener != null) { mLoadListener.onAfterInitialLoad(isReady); } } // other methods}

构造函数在载入 editor.html 之前已经设置了一个 EditorWebViewClient 的实例。

public RichEditor(Context context, AttributeSet attrs, int defStyleAttr) {  // other statements  setWebViewClient(createWebviewClient());  loadUrl(SETUP_HTML)  // other statements}protected EditorWebViewClient createWebviewClient() {  return new EditorWebViewClient();}

editor.html 载入完毕,isReady 被设为 true 之后,exec 方法就能够调用 load(trigger) 运行 js 了。

private void load(String trigger) {  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    evaluateJavascript(trigger, null);  } else {    loadUrl(trigger);  }}

evaluateJavascript 以及 loadUrl 都是 Webview 提供的方法。

evaluateJavascript 是从 API 19 開始引入的。能够异步运行 js 代码。

Asynchronously evaluates JavaScript in the context of the currently displayed page.

SCHEME

RichEditor 提供了两个 Scheme 负责回调 java 代码。

private static final String CALLBACK_SCHEME = "re-callback://";private static final String STATE_SCHEME = "re-state://";

然后在 EditorWebViewClient 中重写了 shouldOverrideUrlLoading 方法:

protected class EditorWebViewClient extends WebViewClient {
@Override public void onPageFinished(WebView view, String url) { isReady = url.equalsIgnoreCase(SETUP_HTML); if (mLoadListener != null) { mLoadListener.onAfterInitialLoad(isReady); } } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { String decode; try { decode = URLDecoder.decode(url, "UTF-8"); } catch (UnsupportedEncodingException e) { // No handling return false; } if (TextUtils.indexOf(url, CALLBACK_SCHEME) == 0) { callback(decode); return true; } else if (TextUtils.indexOf(url, STATE_SCHEME) == 0) { stateCheck(decode); return true; } return super.shouldOverrideUrlLoading(view, url); }}

假设 url 符合 CALLBACK 的 scheme,就会运行 callback 方法:

private void callback(String text) {  mContents = text.replaceFirst(CALLBACK_SCHEME, "");  if (mTextChangeListener != null) {    mTextChangeListener.onTextChange(mContents);  }}

假设 url 符合 STATE 的 scheme。就会运行 stateCheck 方法:

private void stateCheck(String text) {  String state = text.replaceFirst(STATE_SCHEME, "").toUpperCase(Locale.ENGLISH);  List
types = new ArrayList<>(); for (Type type : Type.values()) { if (TextUtils.indexOf(state, type.name()) != -1) { types.add(type); } } if (mDecorationStateListener != null) { mDecorationStateListener.onStateChangeListener(state, types); }}

通过下面两个 set 方法能够设置回调。

public void setOnDecorationChangeListener(OnDecorationStateListener listener) {  mDecorationStateListener = listener;}public void setOnInitialLoadListener(AfterInitialLoadListener listener) {  mLoadListener = listener;}

总结

编辑器的核心功能由 js 实现,RichEditor 封装了 js 的功能。为上层提供了 java 接口。

參考

转载于:https://www.cnblogs.com/lxjshuju/p/7209882.html

你可能感兴趣的文章
胡适阅读
查看>>
Java中日期的转化
查看>>
小程序弱网环境卡顿怎么办?一招迅速提升小程序运行速度
查看>>
管线【十八】
查看>>
重温设计模式 - 建造者模式
查看>>
Android开发 LevelListDrawable详解
查看>>
数组与字符串相互转换的方法总结
查看>>
Firefly安装说明 与 常见问题
查看>>
WP8:在Unity中使用OpenXLive
查看>>
Unity3d 接入 移动MM支付SDK(2.3) 全攻略
查看>>
ubuntu搭建svn服务器并htpp访问版本库并svn与web同步
查看>>
老系统如何引入更新的编码规范
查看>>
开发的模式总结
查看>>
Redis对象的数据结构基础理解
查看>>
SpringBoot非官方教程 | 第十八篇: 定时任务(Scheduling Tasks)
查看>>
Node.js在跑Express的时候有个时候会卡住按一下Ctrl+C又好了的解决办法
查看>>
Windows平台上使用ANT编译Hadoop Eclipse Plugin
查看>>
学习:MQTT协议及原理
查看>>
PAT乙级.1006.换个格式输出整数
查看>>
本地aar文件引用
查看>>