Tengo un problema con el retroceso del teclado virtual en Android (4.2).
Tengo un editor personalizado en un WebView (CodeMirror), que usa un vacío <textarea>
internamente. Parece que un sistema Android no envía el retroceso a menos que crea que hay algún texto en el <textarea>
.
yo he superado WebView
onCreateInputConnection
en un intento de simplificar la entrada suave:
@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;
}
Sin embargo, esto no funciona, e incluso onKeyUp
no se llama para retroceder.
¿Cómo obligo al teclado virtual a enviar siempre retroceso?
Ok, finalmente me di cuenta de esto.
En Android 4.2 (quizás también en versiones anteriores) el retroceso no se envía como un sendKeyEvent(..., KeyEvent.KEYCODE_DEL)
por el teclado virtual estándar. En su lugar, se envía como deleteSurroundingText(1, 0)
.
Así que la solución en mi caso es hacer un custom InputConnection
con lo siguiente:
@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);
}
Nota: avíseme si estoy haciendo algo estúpido aquí, ya que es mi tercer día escribiendo para Android.
este codigo sera mejor, funciona con mas teclado 😀
@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) ;
}
}
.