APK:https://github.com/RexSuper/RichEditor/blob/master/RichHtmlEditorforAndroid/sample/release/sample-release.apk
Demo
https://github.com/RexSuper/RichEditor/tree/master/RichHtmlEditorforAndroid/sample
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.RexSuper:RichEditor:1.0.5'
}
github上的示例代码必须看,因为富文本有些功能后续不得不自己填充,比如用户的资源文件得先放到自己服务器生成链接等等
2019-09-04 优化用户体验,在编辑时候所有资源改为本地,加载转在线改为,最后统一发布的时候
2019-08-20 增加音频功能 增加链接下载功能 和视频下载功能
2019-08-16 增加各种文件功能
2019-08-15 增加添加视频功能
2019-06-21 增加基本图文混排等功能
目录
源码下载
前言:
简单版图例
基本原理:最小模型示例
asset里面放置一些静态网页和我们需要的初始化css
一个简单的带 contenteditable="true"的内容
安卓通过js和html互相调用 例如设置加粗
Webview中调用js中的加粗
1.网页的contenteditable如何实现hint功能
2.如何获取光标所在文字的所有style(需求场景 如选中了加粗 B变色,但你光标选中了)
4.如何自动换行
5.如何处理图片
6.自带只能实现固定几种的font size (1-7自带几种)怎么指定大小实现font-size
7.webview和js交互
8.如何在客户端load自带美化的css解决
9.事件监听
源码下载
10.添加视频
特别鸣谢
结尾:
富文本显示还好,Android富文本编辑一直是一个大坑,还得考虑和其他端同步的问题,问题是你无论用什么方式实现,EditText支持的标签并不多,自定义span或者webview自定义标签也较为繁琐。
用html+webview+js肯定是最合适的可直接导出html兼容性高,Android端用js调用本地静态网页中的contenteditable(此原理做IOS富文本编辑可以无缝照搬)
本文致力于网络常见能搜到的功能实现原理外,补全其他可能遇到的坑,网上能搜到的内容只提关键字
本文也是基础RichEditor for Android思路上一个优化和讲解。它提供了如何和html edit之间交流。理论上来说html能实现的安卓就能实现了,我们只是需要找到这些我们需要的方法
Video | Image | Audio | File And Download |
Italic | Subscript | Superscript | Strikethrough |
Underline | JustifyLeft | JustifyCenter | JustifyRight |
Blockquote | Heading | Undo | Redo |
Indent | Outdent | InsertLink | Checkbox |
TextColor | TextBackgroundColor | FontSize | UnorderedList |
OrderedList | Hint | NewLine | Blod |
editor.html
rich_editor.js
RE.editor = document.getElementById('editor');
RE.setBold = function() {
document.execCommand('bold', false, null);
}
//简化最小模型代码
public void setBold() {
exec("javascript:RE.setBold();");
}
public void exec(String trigger) {
load(trigger)
}
private void load(String trigger) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
evaluateJavascript(trigger, null);
} else {
loadUrl(trigger);
}
}
方法1:
editor.html
Document
方法2
js
RE.setPlaceholder = function(placeholder) {
RE.editor.setAttribute("placeholder", placeholder);
}
css
#editor[placeholder]:empty:not(:focus):before {
content: attr(placeholder);
color: #9B9B9B;
font-size:15px;
}}
抽取成设置方法
public void setPlaceholderColor(String color) {
exec("javascript:RE.setPlaceholderColor('" + color+ "');");
}
rich_editor.js
配合7:addEventListener
RE.getSelectedNode = function() {
var node,selection;
if (window.getSelection) {
selection = getSelection();
node = selection.anchorNode;
}
if (!node && document.selection) {
selection = document.selection
var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange();
node = range.commonAncestorContainer ? range.commonAncestorContainer :
range.parentElement ? range.parentElement() : range.item(0);
}
if (node) {
var item = (node.nodeName == "#text" ? node.parentNode : node);
console.log("innerHTML:"+item.innerHTML);
console.log("font-size:"+item.style["font-size"]);
console.log("color:"+item.getAttribute("color"));
console.log("queryCommandState1 bold:"+document.queryCommandState('bold'));
}
}
public void setNewLine() {
exec("javascript:RE.prepareInsert();");
exec("javascript:RE.insertHTML('
');");
}
5.1安卓实现webview图片点击放大方法回调
这种方式比网上搜出来PageFinish后要好
loadUrl("javascript:(function())有时候会因为加载问题,导致代码没添加进去,那种有bug
现提供更好的方式,同时实现的
public final static String IMG_CLICK_JS = "";
*你也可以按照7.webview和js交互 console.log()传值方式 替换window.imageOnclick.openImage(src);"
将上面代码 直接加入到你的html中
实现对应回调
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new JavascriptInterfaceImageOnclick(), "imageOnclick");
private class JavascriptInterfaceImageOnclick {
@android.webkit.JavascriptInterface
public void openImage(String imgUrl) {
if (mOnClickImageTagListener != null && !TextUtils.isEmpty(imgUrl)) {
mOnClickImageTagListener.onClick(imgUrl);
}
}
}
//待更新
font size 类似于
addJavascriptInterface
removeJavascriptInterface
evaluateJavascript
一般是addJavascriptInterface或者
shouldOverrideUrlLoading
接收信息
其实最好用的是,也最安全
console.log() webview接收
editor(WebView)-->webChromeClient -->onConsoleMessage
1.不可二次编辑
loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl)
2.可二次编辑
editor.loadCSS("file:///android_asset/article_night.css")
无法继续编辑的问题
RE.editor.addEventListener("input", RE.callback);//其他html支持的 keyup ,selectionchange都支持 选中 文本变化 可以查下资料
https://github.com/RexSuper/RichHtmlEditorForAndroid
一定要理解,不然产品随便有个新需求你将寸步难行
// 让其可以继续进去编辑模式
RE.insertVideo = function(url,custom) {
var html = ' ';
RE.insertHTML(html);
}
private void addVideo() {
//需要编辑框有光标才行
richEditor.focusEditor();
// pb.setVisibility(View.VISIBLE);
//将视频上传到自己服务器得到链接
//============>
richEditor.setNeedSetNewLineAfter(true);
richEditor.insertVideo("https://www.w3school.com.cn/example/html5/mov_bbb.mp4",
//增加进度控制
"controls=\"controls\"" +
//视频显示第一帧
" initial-time=\"0.01\" " +
//宽高
"height=\"300\" " +
//样式
" style=\"margin-top:10px;max-width:100%;\""
);
}
function insertHtml(html) {
var sel,range,div,node
sel = window.getSelection()//返回一个Selection对象,用来表示用户选择的文本范围或插入符当前位置。
range = sel.getRangeAt(0) //获取Range,参数为0或其他能够==0,如false,'',null
div=document.createElement('div')
div.innerHTML=html
node=div.firstChild
range.deleteContents()//删除目前range的内容
range.insertNode(node)//新增的节点内容
range.setStartAfter(node)//重新定位range(光标位置)
sel.removeAllRanges() //清除所有选中
sel.addRange(range) //将新定位的range加入
}
思路参考 RichEditor for Android
前端知识修正:@ZX
这是一个不该由客户端实现又可以实现的功能