Android: Retroceso en WebView/BaseInputConnection

2 minutos de lectura

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.

  • Oye, también me encuentro con este problema… excepto que estoy usando Phonegap, por lo que realmente no tengo mucho acceso de bajo nivel al código fuente de Java, ya que todo está compilado. Solo tengo acceso al método onCreate, todo lo demás está ofuscado/compilado. ¿Alguna sugerencia?

    – Nisk

    10 mayo 2013 en 21:44

  • Lo siento, nunca he usado PhoneGap, por lo que no puedo responder a su pregunta, pero intente hacerla como una pregunta separada y debería haber personas familiarizadas con ella.

    – Andrei Shchekin

    11 mayo 2013 en 01:24

  • Gracias de todos modos, publiqué la pregunta, en caso de que quiera vigilarla: stackoverflow.com/questions/16499178/…

    – Nisk

    11 mayo 2013 en 16:12

  • Buen hallazgo Esto me estaba volviendo loco.

    –André Restivo

    09 jun.

  • Muy buen hallazgo. Gracias amigo.

    – Sean Glover

    12 sep.

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

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad