Android TextField: establezca el enfoque + entrada suave mediante programación

81

En mi opinión, tengo una búsqueda EditText y me gustaría activar programáticamente el comportamiento de un evento de clic en el campo, es decir, enfocar el campo de texto Y mostrar el teclado en pantalla si es necesario (si no hay un teclado físico disponible).

Lo intenté field.requestFocus(). El campo se enfoca realmente pero no se muestra el teclado virtual.

Lo intenté field.performClick(). Pero eso solo llama al OnClickListener del campo.

Alguna idea ?

sdabet
fuente

Respuestas:

149

Buen señor, intente esto:

edittext.setFocusableInTouchMode(true);
edittext.requestFocus();

No estoy seguro, pero esto podría ser necesario en algunos teléfonos (algunos de los dispositivos más antiguos):

final InputMethodManager inputMethodManager = (InputMethodManager) context
                .getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT);
pgsandstrom
fuente
3
El mismo resultado que requestFocus () solo ... El campo se enfoca pero el teclado virtual no se activa.
sdabet
12
Finalmente resolví el emitido llamando field.requestFocus()al onResume()método de la actividad (en lugar de onCreate()). No sé exactamente por qué funciona ...
sdabet
31
Una vista no puede enfocarse antes de que realmente se haya presentado en la pantalla. Esto no se puede hacer mientras onCreate () contiene el subproceso UI, por lo tanto, la vista se presenta directamente después de onCreate () y antes de onResume (). :)
pgsandstrom
@fiddler Funciona onResumeporque onResumese llama después onCreate, por lo fieldque no existe hasta que onCreatese ejecuta. Vea aquí: developer.android.com/reference/android/app/…
Randy
3
Excelente sugerencia, viejo cap. Yo declaro; ¡Esto bien merece un voto positivo!
MW.
63

Aquí está el código que funcionó para mí.

edittext.post(new Runnable() {
    public void run() {
        edittext.requestFocusFromTouch();
        InputMethodManager lManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); 
        lManager.showSoftInput(edittext, 0);
    }
});

¡Eso es! Disfruta;)

elisabel
fuente
1
Gracias y este funcionó para mí. Agrego EditTextprogramáticamente cuando el usuario presiona el botón.
dumbfingers
Agregué un EditTextdesde un modal de diálogo. Android establece algunas banderas que hacen que este control no reciba ningún toque. Si agrega el campo en el ejecutable, las banderas no se establecen.
JeffRegan
Parece que el InputTypedel EditTextse está configurado en nulo por Android. Si configura el InputType, debería funcionar.
JeffRegan
La única solución que funciona para mí (si uso InputMethodManager para mostrar el teclado forzado, entonces no puedo ocultarlo)
Pavel
Ninguno de los otros métodos funcionó para mí, pero este sí. Quería tener un cuadro para que los usuarios hicieran clic para abrir la vista de diálogo de edición en lugar de tener una línea de edición para hacer clic en una vista de EditarTexto. En un teléfono, la línea de edición pierde la mayor parte de su funcionalidad, ya que la vista del diálogo de edición cubre la pantalla completa, por lo que el usuario no puede ver la línea de edición, incluidas las letras que aparecen en ella mientras escribe, de todos modos.
Androidcoder
6

El siguiente código funcionó para mí , después de que las otras dos respuestas no funcionaron para mí :

@Override
public void onResume() {
    super.onResume();
    SingletonBus.INSTANCE.getBus().register(this);
    //passwordInput.requestFocus(); <-- that doesn't work
    passwordInput.postDelayed(new ShowKeyboard(), 300); //250 sometimes doesn't run if returning from LockScreen
}

Donde ShowKeyboardesta

private class ShowKeyboard implements Runnable {
    @Override
    public void run() {
        passwordInput.setFocusableInTouchMode(true);
  //      passwordInput.requestFocusFromTouch();
        passwordInput.requestFocus();            
        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
    }
}

Después de una entrada exitosa, también me aseguro de ocultar el teclado

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(getView().getWindowToken(), 0);

Técnicamente, acabo de agregar 300 ms de retraso antes de ejecutar la solicitud de visualización del teclado en pantalla. Extraño, ¿verdad? También cambiado requestFocus()a requestFocusFromTouch().

EDITAR: No lo use, requestFocusFromTouch()le da un evento táctil al lanzador. Quédate con requestFocus().

EDIT2: En Dialogs ( DialogFragment), use lo siguiente

getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

en vez de

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
EpicPandaForce
fuente
requestFocusFromTouch()parece desencadenar un evento táctil en el lanzador. Esto es raro.
EpicPandaForce
0
        field.post(new Runnable() {
            @Override
            public void run() {
                field.requestFocus();
                field.onKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
            }
        });
Intra
fuente
0

En mi caso, quería mostrar el teclado virtual sin referencia a un cuadro de texto específico, así que usé la primera parte de la respuesta aceptada para enfocar :

edittext.setFocusableInTouchMode(true);
edittext.requestFocus();

Luego muestro el teclado virtual :

InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
Dependencia Infierno
fuente