Android开发

Android富文本编辑器添加表情

2020-11-18  本文已影响0人  你的益达233

原来编辑器是没法输入表情的

原来的rich_editor.js是下面这样的

/**
 * Copyright (C) 2015 Wasabeef
 *
 * 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.
 */

var RE = {};

RE.currentSelection = {
"startContainer": 0,
"startOffset": 0,
"endContainer": 0,
"endOffset": 0};

RE.editor = document.getElementById('editor');

document.addEventListener("selectionchange", function() { RE.backuprange(); });

// Initializations
RE.callback = function() {
   var ranges = [
 '\ud83c[\udf00-\udfff]',
 '\ud83d[\udc00-\ude4f]',
 '\ud83d[\ude80-\udeff]'
 ];

var oldlen=RE.editor.innerHTML;
var newlen=RE.editor.innerHTML.replace(new RegExp(ranges.join('|'), 'g'), '');

if(oldlen!=newlen){
RE.backuprange();
RE.editor.innerHTML =  RE.editor.innerHTML.replace(new RegExp(ranges.join('|'), 'g'), '');
RE.restorerange();
}
//RE.editor.focus();
window.location.href = "re-callback://" + encodeURI(RE.getHtml());
}

RE.setHtml = function(contents) {
RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));
}

RE.getHtml = function() {

var ranges = [
'\ud83c[\udf00-\udfff]',
'\ud83d[\udc00-\ude4f]',
'\ud83d[\ude80-\udeff]'
];

return RE.editor.innerHTML.replace(new RegExp(ranges.join('|'), 'g'), '');
}

RE.getText = function() {
return RE.editor.innerText;
}

RE.setBaseTextColor = function(color) {
RE.editor.style.color  = color;
}

RE.setBaseFontSize = function(size) {
RE.editor.style.fontSize = size;
}

RE.setPadding = function(left, top, right, bottom) {
  RE.editor.style.paddingLeft = left;
  RE.editor.style.paddingTop = top;
  RE.editor.style.paddingRight = right;
  RE.editor.style.paddingBottom = bottom;
}

RE.setBackgroundColor = function(color) {
document.body.style.backgroundColor = color;
}

RE.setBackgroundImage = function(image) {
RE.editor.style.backgroundImage = image;
}

RE.setWidth = function(size) {
RE.editor.style.minWidth = size;
}

RE.setHeight = function(size) {
RE.editor.style.height = size;
}

RE.setTextAlign = function(align) {
RE.editor.style.textAlign = align;
}

RE.setVerticalAlign = function(align) {
RE.editor.style.verticalAlign = align;
}

RE.setPlaceholder = function(placeholder) {
RE.editor.setAttribute("placeholder", placeholder);
}

RE.undo = function() {
document.execCommand('undo', false, null);
}

RE.redo = function() {
document.execCommand('redo', false, null);
}

RE.setBold = function() {
document.execCommand('bold', false, null);
}

RE.setItalic = function() {
document.execCommand('italic', false, null);
}

RE.setSubscript = function() {
document.execCommand('subscript', false, null);
}

RE.setSuperscript = function() {
document.execCommand('superscript', false, null);
}

RE.setStrikeThrough = function() {
document.execCommand('strikeThrough', false, null);
}

RE.setUnderline = function() {
document.execCommand('underline', false, null);
}

RE.setBullets = function() {
document.execCommand('InsertUnorderedList', false, null);
}
RE.setBullets = function(b) {
document.execCommand('InsertUnorderedList', false, b);
//if(b){
//document.execCommand('InsertUnorderedList', false, b);
//}else{
//document.execCommand('InsertUnorderedList', false, null);
//}
}
RE.setNumbers = function() {
document.execCommand('InsertOrderedList', false, null);
}
RE.setNumbers = function(b) {
document.execCommand('InsertOrderedList', false, b);
//if(b){
//document.execCommand('InsertOrderedList', false, b);
//  }else{
//document.execCommand('InsertOrderedList', false, null);
//  }
}
RE.setTextColor = function(color) {
RE.restorerange();
document.execCommand("styleWithCSS", null, true);
document.execCommand('foreColor', false, color);
document.execCommand("styleWithCSS", null, false);
}

RE.setTextBackgroundColor = function(color) {
RE.restorerange();
document.execCommand("styleWithCSS", null, true);
document.execCommand('hiliteColor', false, color);
document.execCommand("styleWithCSS", null, false);
}

RE.setFontSize = function(fontSize){
document.execCommand("fontSize", false, fontSize);
}

RE.setHeading = function(heading,b) {
if(b)
document.execCommand('formatBlock', false, '<h'+heading+'>');
else
document.execCommand('formatBlock', false, '<p>');
}

RE.setIndent = function() {
document.execCommand('indent', false, null);
}

RE.setOutdent = function() {
document.execCommand('outdent', false, null);
}

RE.setJustifyLeft = function() {
document.execCommand('justifyLeft', false, null);
}

RE.setJustifyCenter = function() {
document.execCommand('justifyCenter', false, null);
}

RE.setJustifyRight = function() {
document.execCommand('justifyRight', false, null);
}

RE.setBlockquote = function(b) {
if(b)
document.execCommand('formatBlock', false, '<blockquote>');
else
document.execCommand('formatBlock', false, '<p>');
}

//插入图片
RE.insertImage = function(url, alt) {
//var html = '<img  src="' + url + '" alt="' + alt + '" /><p align=center style="color:#aaaaaa">来自陌筹君App的图片</p><hr align=center width=200 color=#aaaaaa size=1 /><br/><br/>';
var html = '<img  src="' + url + '" /><br/><br/>';
RE.insertHTML(html);
}

//插入分割线
RE.insertHr = function() {
var html = '<hr color=#e2e2e2 size=1 /><br/>';
RE.insertHTML(html);
}

RE.insertHTML = function(html) {
RE.restorerange();
document.execCommand('insertHTML', false, html);
}

RE.insertLink = function(url, title) {
RE.restorerange();
var sel = document.getSelection();
if (sel.toString().length == 0) {
document.execCommand("insertHTML",false,"<a href='"+url+"'>"+title+"</a>");
} else if (sel.rangeCount) {
   var el = document.createElement("a");
   el.setAttribute("href", url);
   el.setAttribute("title", title);

   var range = sel.getRangeAt(0).cloneRange();
   range.surroundContents(el);
   sel.removeAllRanges();
   sel.addRange(range);
   }
RE.callback();
}

RE.setTodo = function(text) {
var html = '<input type="checkbox" name="'+ text +'" value="'+ text +'"/> &nbsp;';
document.execCommand('insertHTML', false, html);
}

RE.prepareInsert = function() {
RE.backuprange();
}

RE.backuprange = function(){
var selection = window.getSelection();
if (selection.rangeCount > 0) {
  var range = selection.getRangeAt(0);
  RE.currentSelection = {
  "startContainer": range.startContainer,
  "startOffset": range.startOffset,
  "endContainer": range.endContainer,
  "endOffset": range.endOffset};
}
}

RE.restorerange = function(){
var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
selection.addRange(range);
}

RE.enabledEditingItems = function(e) {
var items = [];

if (document.queryCommandState('bold')) {
items.push('bold');
}
if (document.queryCommandState('italic')) {
items.push('italic');
}
if (document.queryCommandState('subscript')) {
items.push('subscript');
}
if (document.queryCommandState('superscript')) {
items.push('superscript');
}
if (document.queryCommandState('strikeThrough')) {
items.push('strikeThrough');
}
if (document.queryCommandState('underline')) {
items.push('underline');
}
if (document.queryCommandState('insertOrderedList')) {
items.push('orderedList');
}
if (document.queryCommandState('insertUnorderedList')) {
items.push('unorderedList');
}
if (document.queryCommandState('justifyCenter')) {
items.push('justifyCenter');
}
if (document.queryCommandState('justifyFull')) {
items.push('justifyFull');
}
if (document.queryCommandState('justifyLeft')) {
items.push('justifyLeft');
}
if (document.queryCommandState('justifyRight')) {
items.push('justifyRight');
}
if (document.queryCommandState('insertHorizontalRule')) {
items.push('horizontalRule');
}
var formatBlock = document.queryCommandValue('formatBlock');
if (formatBlock.length > 0) {
items.push(formatBlock);
}

if(e.which==13){
items.push("enter");
}


var ranges = [
'\ud83c[\udf00-\udfff]',
'\ud83d[\udc00-\ude4f]',
'\ud83d[\ude80-\udeff]'
];

window.location.href = "re-state://" + encodeURI(items.join(','))+"@_@"+encodeURI(RE.getHtml());
}

RE.focus = function() {
var range = document.createRange();
range.selectNodeContents(RE.editor);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
RE.editor.focus();
}

RE.blurFocus = function() {
RE.editor.blur();
}

RE.removeFormat = function() {
execCommand('removeFormat', false, null);
}

// Event Listeners
RE.editor.addEventListener("input", RE.callback);
RE.editor.addEventListener("keyup", function(e) {
//RE.enabledEditingItems(e);
   var KEY_LEFT = 37, KEY_RIGHT = 39;
   if (e.which == KEY_LEFT || e.which == KEY_RIGHT || e.which ==8 || e.which == 13) {
   RE.enabledEditingItems(e);
   }
});
RE.editor.addEventListener("click", RE.enabledEditingItems);

主要是

var ranges = [
     '\ud83c[\udf00-\udfff]',
     '\ud83d[\udc00-\ude4f]',
     '\ud83d[\ude80-\udeff]'
 ];

这样的代码是表情的,它全都替换为空格了
好处:****本来WebView直接显示表情是有问题的,所以它适用于不需要表情的需求,也是不错的

修改rich_editor.js文件

/**
 * Copyright (C) 2015 Wasabeef
 *
 * 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.
 */

var RE = {};

RE.currentSelection = {
"startContainer": 0,
"startOffset": 0,
"endContainer": 0,
"endOffset": 0};

RE.editor = document.getElementById('editor');

document.addEventListener("selectionchange", function() { RE.backuprange(); });

// Initializations
RE.callback = function() {
//   var ranges = [
// '\ud83c[\udf00-\udfff]',
// '\ud83d[\udc00-\ude4f]',
// '\ud83d[\ude80-\udeff]'
// ];
//
//var oldlen=RE.editor.innerHTML;
////var newlen=RE.editor.innerHTML.replace(new RegExp(ranges.join('|'), 'g'), '');
//
//if(oldlen!=newlen){
//RE.backuprange();
////RE.editor.innerHTML =  RE.editor.innerHTML.replace(new RegExp(ranges.join('|'), 'g'), '');
//RE.restorerange();
//}
//RE.editor.focus();
window.location.href = "re-callback://" + encodeURI(RE.getHtml());
}

RE.setHtml = function(contents) {
RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));
}

RE.getHtml = function() {

//var ranges = [
//'\ud83c[\udf00-\udfff]',
//'\ud83d[\udc00-\ude4f]',
//'\ud83d[\ude80-\udeff]'
//];

return RE.editor.innerHTML;
}

RE.getText = function() {
return RE.editor.innerText;
}

RE.setBaseTextColor = function(color) {
RE.editor.style.color  = color;
}

RE.setBaseFontSize = function(size) {
RE.editor.style.fontSize = size;
}

RE.setPadding = function(left, top, right, bottom) {
  RE.editor.style.paddingLeft = left;
  RE.editor.style.paddingTop = top;
  RE.editor.style.paddingRight = right;
  RE.editor.style.paddingBottom = bottom;
}

RE.setBackgroundColor = function(color) {
document.body.style.backgroundColor = color;
}

RE.setBackgroundImage = function(image) {
RE.editor.style.backgroundImage = image;
}

RE.setWidth = function(size) {
RE.editor.style.minWidth = size;
}

RE.setHeight = function(size) {
RE.editor.style.height = size;
}

RE.setTextAlign = function(align) {
RE.editor.style.textAlign = align;
}

RE.setVerticalAlign = function(align) {
RE.editor.style.verticalAlign = align;
}

RE.setPlaceholder = function(placeholder) {
RE.editor.setAttribute("placeholder", placeholder);
}

RE.undo = function() {
document.execCommand('undo', false, null);
}

RE.redo = function() {
document.execCommand('redo', false, null);
}

RE.setBold = function() {
document.execCommand('bold', false, null);
}

RE.setItalic = function() {
document.execCommand('italic', false, null);
}

RE.setSubscript = function() {
document.execCommand('subscript', false, null);
}

RE.setSuperscript = function() {
document.execCommand('superscript', false, null);
}

RE.setStrikeThrough = function() {
document.execCommand('strikeThrough', false, null);
}

RE.setUnderline = function() {
document.execCommand('underline', false, null);
}

RE.setBullets = function() {
document.execCommand('InsertUnorderedList', false, null);
}
RE.setBullets = function(b) {
document.execCommand('InsertUnorderedList', false, b);
//if(b){
//document.execCommand('InsertUnorderedList', false, b);
//}else{
//document.execCommand('InsertUnorderedList', false, null);
//}
}
RE.setNumbers = function() {
document.execCommand('InsertOrderedList', false, null);
}
RE.setNumbers = function(b) {
document.execCommand('InsertOrderedList', false, b);
//if(b){
//document.execCommand('InsertOrderedList', false, b);
//  }else{
//document.execCommand('InsertOrderedList', false, null);
//  }
}
RE.setTextColor = function(color) {
RE.restorerange();
document.execCommand("styleWithCSS", null, true);
document.execCommand('foreColor', false, color);
document.execCommand("styleWithCSS", null, false);
}

RE.setTextBackgroundColor = function(color) {
RE.restorerange();
document.execCommand("styleWithCSS", null, true);
document.execCommand('hiliteColor', false, color);
document.execCommand("styleWithCSS", null, false);
}

RE.setFontSize = function(fontSize){
document.execCommand("fontSize", false, fontSize);
}

RE.setHeading = function(heading,b) {
if(b)
document.execCommand('formatBlock', false, '<h'+heading+'>');
else
document.execCommand('formatBlock', false, '<p>');
}

RE.setIndent = function() {
document.execCommand('indent', false, null);
}

RE.setOutdent = function() {
document.execCommand('outdent', false, null);
}

RE.setJustifyLeft = function() {
document.execCommand('justifyLeft', false, null);
}

RE.setJustifyCenter = function() {
document.execCommand('justifyCenter', false, null);
}

RE.setJustifyRight = function() {
document.execCommand('justifyRight', false, null);
}

RE.setBlockquote = function(b) {
if(b)
document.execCommand('formatBlock', false, '<blockquote>');
else
document.execCommand('formatBlock', false, '<p>');
}

//插入图片
RE.insertImage = function(url, alt) {
//var html = '<img  src="' + url + '" alt="' + alt + '" /><p align=center style="color:#aaaaaa">来自陌筹君App的图片</p><hr align=center width=200 color=#aaaaaa size=1 /><br/><br/>';
var html = '<img  src="' + url + '" /><br/><br/>';
RE.insertHTML(html);
//var html = '<img src="' + url + '" alt="' + alt + '" />';
//RE.insertHTML(html);
}

//插入分割线
RE.insertHr = function() {
var html = '<hr color=#e2e2e2 size=1 /><br/>';
RE.insertHTML(html);
}

RE.insertHTML = function(html) {
RE.restorerange();
document.execCommand('insertHTML', false, html);
}

RE.insertLink = function(url, title) {
RE.restorerange();
var sel = document.getSelection();
if (sel.toString().length == 0) {
document.execCommand("insertHTML",false,"<a href='"+url+"'>"+title+"</a>");
} else if (sel.rangeCount) {
   var el = document.createElement("a");
   el.setAttribute("href", url);
   el.setAttribute("title", title);

   var range = sel.getRangeAt(0).cloneRange();
   range.surroundContents(el);
   sel.removeAllRanges();
   sel.addRange(range);
   }
RE.callback();
}

RE.setTodo = function(text) {
var html = '<input type="checkbox" name="'+ text +'" value="'+ text +'"/> &nbsp;';
document.execCommand('insertHTML', false, html);
}

RE.prepareInsert = function() {
RE.backuprange();
}

RE.backuprange = function(){
var selection = window.getSelection();
if (selection.rangeCount > 0) {
  var range = selection.getRangeAt(0);
  RE.currentSelection = {
  "startContainer": range.startContainer,
  "startOffset": range.startOffset,
  "endContainer": range.endContainer,
  "endOffset": range.endOffset};
}
}

RE.restorerange = function(){
var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
selection.addRange(range);
}

RE.enabledEditingItems = function(e) {
var items = [];

if (document.queryCommandState('bold')) {
items.push('bold');
}
if (document.queryCommandState('italic')) {
items.push('italic');
}
if (document.queryCommandState('subscript')) {
items.push('subscript');
}
if (document.queryCommandState('superscript')) {
items.push('superscript');
}
if (document.queryCommandState('strikeThrough')) {
items.push('strikeThrough');
}
if (document.queryCommandState('underline')) {
items.push('underline');
}
if (document.queryCommandState('insertOrderedList')) {
items.push('orderedList');
}
if (document.queryCommandState('insertUnorderedList')) {
items.push('unorderedList');
}
if (document.queryCommandState('justifyCenter')) {
items.push('justifyCenter');
}
if (document.queryCommandState('justifyFull')) {
items.push('justifyFull');
}
if (document.queryCommandState('justifyLeft')) {
items.push('justifyLeft');
}
if (document.queryCommandState('justifyRight')) {
items.push('justifyRight');
}
if (document.queryCommandState('insertHorizontalRule')) {
items.push('horizontalRule');
}
var formatBlock = document.queryCommandValue('formatBlock');
if (formatBlock.length > 0) {
items.push(formatBlock);
}

if(e.which==13){
items.push("enter");
}


//var ranges = [
//'\ud83c[\udf00-\udfff]',
//'\ud83d[\udc00-\ude4f]',
//'\ud83d[\ude80-\udeff]'
//];

//window.location.href = "re-state://" + encodeURI(items.join(','))+"@_@"+encodeURI(RE.getHtml());
window.location.href = "re-state://" + encodeURI(items.join(','));
}

RE.focus = function() {
var range = document.createRange();
range.selectNodeContents(RE.editor);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
RE.editor.focus();
}

RE.blurFocus = function() {
RE.editor.blur();
}

RE.removeFormat = function() {
execCommand('removeFormat', false, null);
}

// Event Listeners
RE.editor.addEventListener("input", RE.callback);
RE.editor.addEventListener("keyup", function(e) {
//RE.enabledEditingItems(e);
   var KEY_LEFT = 37, KEY_RIGHT = 39;
   if (e.which == KEY_LEFT || e.which == KEY_RIGHT || e.which ==8 || e.which == 13) {
   RE.enabledEditingItems(e);
   }
});
RE.editor.addEventListener("click", RE.enabledEditingItems);

看到没,重点把表情的代码放出来
注意:记得editor.html中的js改为你修改后的xx.js

直接给ACRichEmojiEditor

package com.xf.activity.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;



import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;



public class ACRichEmojiEditor extends WebView {

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

public interface OnTextChangeListener {

    void onTextChange(String text);
}

public interface OnDecorationStateListener {

    void onStateChangeListener(String text, List<Type> types);
}

public interface AfterInitialLoadListener {

    void onAfterInitialLoad(boolean isReady);
}

private static final String SETUP_HTML = "file:///android_asset/editor3.html";
private static final String CALLBACK_SCHEME = "re-callback://";
private static final String STATE_SCHEME = "re-state://";
private boolean isReady = false;
private String mContents;
private OnTextChangeListener mTextChangeListener;
private OnDecorationStateListener mDecorationStateListener;
private AfterInitialLoadListener mLoadListener;
private OnScrollChangedCallback mOnScrollChangedCallback;

public ACRichEmojiEditor(Context context) {
    this(context, null);
}

public ACRichEmojiEditor(Context context, AttributeSet attrs) {
    this(context, attrs, android.R.attr.webViewStyle);
}

@SuppressLint("SetJavaScriptEnabled")
public ACRichEmojiEditor(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    setVerticalScrollBarEnabled(false);
    setHorizontalScrollBarEnabled(false);
    getSettings().setJavaScriptEnabled(true);
    setWebChromeClient(new WebChromeClient());
    setWebViewClient(createWebviewClient());
    loadUrl(SETUP_HTML);

    applyAttributes(context, attrs);
}

protected EditorWebViewClient createWebviewClient() {
    return new EditorWebViewClient();
}

public void setOnTextChangeListener(OnTextChangeListener listener) {
    mTextChangeListener = listener;
}

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

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

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


/**
 * WebView的滚动事件
 *
 * @param l
 * @param t
 * @param oldl
 * @param oldt
 */
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);

    if (mOnScrollChangedCallback != null) {
        mOnScrollChangedCallback.onScroll(l - oldl, t - oldt);
    }

}

public OnScrollChangedCallback getOnScrollChangedCallback() {
    return mOnScrollChangedCallback;
}

public void setOnScrollChangedCallback(
        final OnScrollChangedCallback onScrollChangedCallback) {
    mOnScrollChangedCallback = onScrollChangedCallback;
}


/**
 * Impliment in the activity/fragment/view that you want to listen to the webview
 */
public interface OnScrollChangedCallback {
    void onScroll(int dx, int dy);
}


private void stateCheck(String text) {

    if (!text.contains("@_@")) {
        String state = text.replaceFirst(STATE_SCHEME, "").toUpperCase(Locale.ENGLISH);
        List<Type> 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);
        }
        return;
    }

    String state = text.replaceFirst(STATE_SCHEME, "").split("@_@")[0].toUpperCase(Locale.ENGLISH);
    List<Type> 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);
    }

    if (text.replaceFirst(STATE_SCHEME, "").split("@_@").length > 1) {
        mContents = text.replaceFirst(STATE_SCHEME, "").split("@_@")[1];
        if (mTextChangeListener != null) {
            mTextChangeListener.onTextChange(mContents);
        }
    }
}

private void applyAttributes(Context context, AttributeSet attrs) {
    final int[] attrsArray = new int[]{
            android.R.attr.gravity
    };
    TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);

    int gravity = ta.getInt(0, NO_ID);
    switch (gravity) {
        case Gravity.LEFT:
            exec("javascript:RE.setTextAlign(\"left\")");
            break;
        case Gravity.RIGHT:
            exec("javascript:RE.setTextAlign(\"right\")");
            break;
        case Gravity.TOP:
            exec("javascript:RE.setVerticalAlign(\"top\")");
            break;
        case Gravity.BOTTOM:
            exec("javascript:RE.setVerticalAlign(\"bottom\")");
            break;
        case Gravity.CENTER_VERTICAL:
            exec("javascript:RE.setVerticalAlign(\"middle\")");
            break;
        case Gravity.CENTER_HORIZONTAL:
            exec("javascript:RE.setTextAlign(\"center\")");
            break;
        case Gravity.CENTER:
            exec("javascript:RE.setVerticalAlign(\"middle\")");
            exec("javascript:RE.setTextAlign(\"center\")");
            break;
    }

    ta.recycle();
}

/**
 * setText
 *
 * @param contents
 */
public void setHtml(String contents) {
    if (contents == null) {
        contents = "";
    }
    try {
        exec("javascript:RE.setHtml('" + URLEncoder.encode(contents, "UTF-8") + "');");
    } catch (UnsupportedEncodingException e) {
        // No handling
    }
    mContents = contents;
}

/**
 * getText
 *
 * @return
 */
public String getHtml() {
    return mContents;
}

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

public void setEditorFontSize(int px) {
    exec("javascript:RE.setBaseFontSize('" + px + "px');");
}

@Override
public void setPadding(int left, int top, int right, int bottom) {
    super.setPadding(left, top, right, bottom);
    exec("javascript:RE.setPadding('" + left + "px', '" + top + "px', '" + right + "px', '" + bottom
            + "px');");
}

@Override
public void setPaddingRelative(int start, int top, int end, int bottom) {
    // still not support RTL.
    setPadding(start, top, end, bottom);
}

public void setEditorBackgroundColor(int color) {
    setBackgroundColor(color);
}

@Override
public void setBackgroundColor(int color) {
    super.setBackgroundColor(color);
}

@Override
public void setBackgroundResource(int resid) {
    Bitmap bitmap = ACRichUtils.decodeResource(getContext(), resid);
    String base64 = ACRichUtils.toBase64(bitmap);
    bitmap.recycle();

    exec("javascript:RE.setBackgroundImage('url(data:image/png;base64," + base64 + ")');");
}

@Override
public void setBackground(Drawable background) {
    Bitmap bitmap = ACRichUtils.toBitmap(background);
    String base64 = ACRichUtils.toBase64(bitmap);
    bitmap.recycle();

    exec("javascript:RE.setBackgroundImage('url(data:image/png;base64," + base64 + ")');");
}

public void setBackground(String url) {
    exec("javascript:RE.setBackgroundImage('url(" + url + ")');");
}

public void setEditorWidth(int px) {
    exec("javascript:RE.setWidth('" + px + "px');");
}

public void setEditorHeight(int px) {
    exec("javascript:RE.setHeight('" + px + "px');");
}

public void setPlaceholder(String placeholder) {
    exec("javascript:RE.setPlaceholder('" + placeholder + "');");
}

public void loadCSS(String cssFile) {
    String jsCSSImport = "(function() {" +
            "    var head  = document.getElementsByTagName(\"head\")[0];" +
            "    var link  = document.createElement(\"link\");" +
            "    link.rel  = \"stylesheet\";" +
            "    link.type = \"text/css\";" +
            "    link.href = \"" + cssFile + "\";" +
            "    link.media = \"all\";" +
            "    head.appendChild(link);" +
            "}) ();";
    exec("javascript:" + jsCSSImport + "");
}
public  void setWebImageClick(WebView view) {
    String jsCode="javascript:(function(){" +
            "var imgs=document.getElementsByTagName(\"img\");" +
            " var array=new Array(); " +
            " for(var j=0;j<imgs.length;j++){ array[j]=imgs[j].src; }"+
            "for(var i=0;i<imgs.length;i++){" +

            "imgs[i].onclick=function(){" +
            "window.jsCallJavaObj.openImage(this.src,array);" +
            "}}})()";
    view.loadUrl(jsCode);
}
public  void setWebImageClick() {
    String jsCode="javascript:(function(){" +
            "var imgs=document.getElementsByTagName(\"img\");" +
            " var array=new Array(); " +
            " for(var j=0;j<imgs.length;j++){ array[j]=imgs[j].src; }"+
            "for(var i=0;i<imgs.length;i++){" +

            "imgs[i].onclick=function(){" +
            "window.jsCallJavaObj.openImage(this.src,array);" +
            "}}})()";
    exec("javascript:" + jsCode + "");
}
public void undo() {
    exec("javascript:RE.undo();");
}

public void redo() {
    exec("javascript:RE.redo();");
}

public void setBold() {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.setBold();");
}

public void setItalic() {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.setItalic();");
}

public void setSubscript() {
    exec("javascript:RE.setSubscript();");
}

public void setSuperscript() {
    exec("javascript:RE.setSuperscript();");
}

public void setStrikeThrough() {
    exec("javascript:RE.setStrikeThrough();");
}

public void setUnderline() {
    exec("javascript:RE.setUnderline();");
}

public void setTextColor(int color) {
    exec("javascript:RE.prepareInsert();");

    String hex = convertHexColorString(color);
    exec("javascript:RE.setTextColor('" + hex + "');");
}

public void setTextBackgroundColor(int color) {
    exec("javascript:RE.prepareInsert();");

    String hex = convertHexColorString(color);
    exec("javascript:RE.setTextBackgroundColor('" + hex + "');");
}

public void setFontSize(int fontSize) {
    if (fontSize > 7 || fontSize < 1) {
        Log.e("RichEditor", "Font size should have a value between 1-7");
    }
    exec("javascript:RE.setFontSize('" + fontSize + "');");
}

public void removeFormat() {
    exec("javascript:RE.removeFormat();");
}

public void setHeading(int heading, boolean b, boolean isItalic, boolean isBold, boolean isStrikeThrough) {
    exec("javascript:RE.prepareInsert();");

    exec("javascript:RE.setHeading('" + heading + "'," + b + ");");
}

public void setIndent() {
    exec("javascript:RE.setIndent();");
}

public void setOutdent() {
    exec("javascript:RE.setOutdent();");
}

public void setAlignLeft() {
    exec("javascript:RE.setJustifyLeft();");
}

public void setAlignCenter() {
    exec("javascript:RE.setJustifyCenter();");
}

public void setAlignRight() {
    exec("javascript:RE.setJustifyRight();");
}

public void setBlockquote(boolean b, boolean isItalic, boolean isBold, boolean isStrikeThrough) {
    exec("javascript:RE.prepareInsert();");

    exec("javascript:RE.setBlockquote(" + b + ");");
}

//设置点点
public void setBullets() {
    exec("javascript:RE.setBullets();");
}
//设置点点
public void setBullets(boolean b) {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.setBullets(" + b + ");");
    //Log.d("Acheng",b+":Bullets");
}
//设置数字
public void setNumbers() {
    exec("javascript:RE.setNumbers();");
}
//设置数字
public void setNumbers(boolean b) {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.setNumbers(" + b + ");");
    //Log.d("Acheng",b+":Numbers");
}

public void insertImage(String url, String alt) {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.insertImage('" + url + "', '" + alt + "');");
}

public void insertHr() {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.insertHr();");
}


public void insertLink(String href, String title) {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.insertLink('" + href + "', '" + title + "');");
}

public void insertTodo() {
    exec("javascript:RE.prepareInsert();");
    exec("javascript:RE.setTodo('" + ACRichUtils.getCurrentTime() + "');");
}

public void focusEditor() {
    requestFocus();
    exec("javascript:RE.focus();");
}

public void clearFocusEditor() {
    exec("javascript:RE.blurFocus();");
}

private String convertHexColorString(int color) {
    return String.format("#%06X", (0xFFFFFF & color));
}

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

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

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);
    }
}
}

至此准备操作就好了

使用

要WebView显示是需要编码的
思路:叫了接口配合下。app先编码content传给接口,接口解码做它的处理,处理完再编码传给app。app显示解码即可
编码:

URLEncoder.encode(content, "utf-8").replace("+"," ")  

解码:

wbView?.html = URLDecoderUtil.decode(data.data.content)

ios和Android都用这种编码方式即可

有问题请私信或者评论

上一篇 下一篇

猜你喜欢

热点阅读