I am building a rich text editor in android. To do so, I am using a webView
with a contentEditable div.
To add styles, I invoke JavaScrip
Android: Backspace in WebView/BaseInputConnection
Subclass Webview and override the method as shown by this guy's question.
On some phones, only the guy's question will satisfy the requirements. The link's answer will complete the code for compatibility with other phones. Though, you subclass a InputConnectionWrapper. not inputconnection. and then return that wrapper within your custom webview.
Just a FYI, this link has a much more detailed explanation of the situation, however I tried quickly implementing their ideas and it didn't work. Maybe too complicated for my purposes. The reason I tried their solution instead of what I mentioned above is because the solution I mentioned above causes the voice-to-text function to not work correctly. Android - cannot capture backspace/delete press in soft. keyboard
I have implemented a richTextEditor using WebView
and JavaScript
.
I had no problem in inserting/deleting image that I have added to content editable html page. Code that I have used for inserting image is
String exeSucess = "document.execCommand('insertHtml', false,'<img src=\""
+ selectedImagePath + "\" height=auto width=200 ></img>');";
//Then code for executing this javascript.
Thanks.
<div contenteditable="true"></div>
I use this to do a rich editor in a webview
Then override method TapInputConnection
in 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);
}
}
You have realized that I override sendKeyEvent
and I deal with Delete
Key by myself
This is the delete()
function;
public void delete(){
loadurl("javascript:document.execCommand('delete', false, null);");
}