Не удается удалить изображение в contenteditable div на Android

Я создаю богатый текстовый редактор в android. Для этого я использую webView с contentEditable div.

Чтобы добавить стили, я вызываю JavaScript. Все это работает отлично, за исключением случаев, когда я вызываю JavaScript для вставки изображения или горизонтального правила. Когда я использую JavaScript для вставки этих вещей, если я затем попытаюсь нажать кнопку "Назад", чтобы удалить изображение или горизонтальное правило, это не сработает.

Как ни странно, если я сначала введу какой-либо другой символ, а затем вставьте изображение или горизонтальное правило, я могу просто удалить изображение/горизонтальное правило, но не могу удалить символ, который я ввел непосредственно перед правилом изображения/горизонтали.

Я пробовал распечатывать HTML в каждом состоянии, проверять выбор/диапазон и т.д., и, похоже, не может найти ничего, что отличается от состояния, которое могло бы объяснить, почему я не могу удалить изображение и т.д.

Ответ 1

Android: Backspace в WebView/BaseInputConnection

Подкласс Webview и переопределить метод, как показано этим вопросом парня.

На некоторых телефонах только вопрос парня удовлетворяет требованиям. Ответ на связь завершит код для совместимости с другими телефонами. Хотя, вы подклассифицируете InputConnectionWrapper. не входное соединение. а затем верните эту оболочку в свой собственный веб-просмотр.

Просто FYI, эта ссылка содержит гораздо более подробное объяснение ситуации, однако я попытался быстро реализовать свои идеи, и это не сработало. Возможно, слишком сложно для моих целей. Причина, по которой я пробовал свое решение вместо того, что я упомянул выше, состоит в том, что упомянутое выше решение заставляет функцию голосовой связи работать неправильно. Android - не удается захватить обратное или удалить нажатие на soft. Клавиатура

Ответ 2

Я реализовал richTextEditor, используя WebView и JavaScript.

У меня не было проблем с вставкой/удалением изображения, которое я добавил в content editable html page. Код, который я использовал для вставки изображения,

String exeSucess = "document.execCommand('insertHtml', false,'<img src=\""
        + selectedImagePath + "\" height=auto width=200 ></img>');";
   //Then code for executing this javascript.

Спасибо.

Ответ 3

<div contenteditable="true"></div>

Я использую это для создания богатого редактора в webview

Затем переопределите метод TapInputConnection в Webview

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    return new TapInputConnection(super.onCreateInputConnection(outAttrs));
}



class TapInputConnection implements InputConnection {

    private InputConnection mConnection;


    public TapInputConnection(InputConnection conn){
        this.mConnection = conn;
    }

    @Override
    public CharSequence getTextBeforeCursor(int n, int flags) {
        return mConnection.getTextBeforeCursor(n, flags);
    }

    @Override
    public CharSequence getTextAfterCursor(int n, int flags) {
        return mConnection.getTextAfterCursor(n, flags);
    }

    @Override
    public CharSequence getSelectedText(int flags) {
        return mConnection.getSelectedText(flags);
    }

    @Override
    public int getCursorCapsMode(int reqModes) {
        return mConnection.getCursorCapsMode(reqModes);
    }

    @Override
    public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
        return mConnection.getExtractedText(request, flags);
    }

    @Override
    public boolean deleteSurroundingText(int beforeLength, int afterLength) {
        return mConnection.deleteSurroundingText(beforeLength, afterLength);
    }

    @Override
    public boolean setComposingText(CharSequence text, int newCursorPosition) {
        return mConnection.setComposingText(text, newCursorPosition);
    }

    @Override
    public boolean setComposingRegion(int start, int end) {
        return mConnection.setComposingRegion(start, end);
    }

    @Override
    public boolean finishComposingText() {
        return mConnection.finishComposingText();
    }

    @Override
    public boolean commitText(CharSequence text, int newCursorPosition) {
        return mConnection.commitText(text, newCursorPosition );
    }

    @Override
    public boolean commitCompletion(CompletionInfo text) {
        return mConnection.commitCompletion(text);
    }

    @Override
    public boolean commitCorrection(CorrectionInfo correctionInfo) {
        return mConnection.commitCorrection(correctionInfo);
    }

    @Override
    public boolean setSelection(int start, int end) {
        return mConnection.setSelection(start, end);
    }

    @Override
    public boolean performEditorAction(int editorAction) {
        return mConnection.performEditorAction(editorAction);
    }

    @Override
    public boolean performContextMenuAction(int id) {
        return mConnection.performContextMenuAction(id);
    }

    @Override
    public boolean beginBatchEdit() {
        return mConnection.beginBatchEdit();
    }

    @Override
    public boolean endBatchEdit() {
        return mConnection.endBatchEdit();
    }

    @Override
    public boolean sendKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
            if (event.getAction() == KeyEvent.ACTION_UP) {
                delete();
            }
            return true;
        }
        return mConnection.sendKeyEvent(event);
    }

    @Override
    public boolean clearMetaKeyStates(int states) {
        return false;
    }

    @Override
    public boolean reportFullscreenMode(boolean enabled) {
        return mConnection.reportFullscreenMode(enabled);
    }

    @Override
    public boolean performPrivateCommand(String action, Bundle data) {
        return mConnection.performPrivateCommand(action, data);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean requestCursorUpdates(int cursorUpdateMode) {
        return mConnection.requestCursorUpdates(cursorUpdateMode);
    }
}

Вы поняли, что я переопределяю sendKeyEvent, и я сам использую Delete Key

Это функция delete();

public void delete(){
  loadurl("javascript:document.execCommand('delete', false, null);");
}