Android: Backspace в WebView/BaseInputConnection
У меня проблема с мягким переходом клавиатуры в Android (4.2).
У меня есть собственный редактор в WebView (CodeMirror), который использует пустой <textarea>
внутри. Кажется, что backspace не отправляется системой Android, если не считает, что есть текст в <textarea>
.
Я отключил WebView
onCreateInputConnection
в попытке заглушить мягкий вход:
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
Log.d("CustomWebView", "onCreateInputConnection(...)");
BaseInputConnection connection = new BaseInputConnection(this, false);
outAttrs.inputType = InputType.TYPE_NULL;
outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE;
outAttrs.initialSelStart = -1;
outAttrs.initialSelEnd = -1;
return connection;
}
Однако это не работает, и даже onKeyUp
не вызывается для backspace.
Как заставить мягкую клавиатуру всегда отправлять обратное пространство?
Ответы
Ответ 1
Хорошо, наконец понял это.
В Android 4.2 (возможно, в более ранних версиях) backspace не отправляется как sendKeyEvent(..., KeyEvent.KEYCODE_DEL)
стандартной мягкой клавиатурой. Вместо этого он отправляется как deleteSurroundingText(1, 0)
.
Таким образом, решение в моем случае состоит в создании пользовательского InputConnection
со следующим:
@Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
// magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
if (beforeLength == 1 && afterLength == 0) {
// backspace
return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
&& super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
}
return super.deleteSurroundingText(beforeLength, afterLength);
}
Примечание. Пожалуйста, дайте мне знать, если я делаю что-то глупо здесь, так как это мой третий день для Android.
Ответ 2
этот код будет лучше, он будет работать с большей клавиатурой: D
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.actionLabel = null;
outAttrs.inputType = InputType.TYPE_NULL;
final InputConnection con = new BaseInputConnection(this,false);
InputConnectionWrapper public_con = new InputConnectionWrapper(
super.onCreateInputConnection(outAttrs), true) {
@Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
if (beforeLength == 1 && afterLength == 0) {
return this.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
&& this.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
}
return super.deleteSurroundingText(beforeLength, afterLength);
}
@Override
public boolean sendKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_DEL){
return con.sendKeyEvent(event);
}else {
return super.sendKeyEvent(event);
}
}
};
try {
return public_con ;
}catch (Exception e){
return super.onCreateInputConnection(outAttrs) ;
}
}