¿Cómo puedo configurar el foco (y mostrar el teclado) en mi EditText mediante programación

180

Tengo un diseño que contiene algunas vistas como esta:

<LinearLayout>
<TextView...>
<TextView...>
<ImageView ...>
<EditText...>
<Button...>
</linearLayout>

¿Cómo puedo configurar el foco (mostrar el teclado) en mi EditTextprogramáticamente?

He intentado esto y funciona solo cuando ejecuto mi Activitynormalmente, pero cuando lo ejecuto en un TabHost, no funciona.

txtSearch.setFocusableInTouchMode(true);
txtSearch.setFocusable(true);
txtSearch.requestFocus();
Houcine
fuente

Respuestas:

353

Prueba esto:

EditText editText = (EditText) findViewById(R.id.myTextViewId);
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);

http://developer.android.com/reference/android/view/View.html#requestFocus ()

David Merriman
fuente
Actualizado con código para forzar que el teclado se muestre a partir de esta respuesta: stackoverflow.com/questions/5105354/…
David Merriman
55
funciona solo cuando inicio mi actividad normalmente, pero cuando inicio mi actividad en un TabHost, no funciona,
Houcine
27
Esto no funciona Este funciona para mí InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput (InputMethodManager.SHOW_FORCED, 0);
Günay Gültekin
55
"Esto no funciona hermano". En algunos casos, debe llamar a este código de forma asincrónica desde postDelayed (). Tuve un caso cuando tuve que abrir el teclado después de que el usuario presionó "Aceptar" en el cuadro de diálogo. Y cuando el diálogo se estaba cerrando, estaba jugando con el foco. Entonces llamé al código anterior desde postDelayed (). Se ejecutó después de que se cerró el diálogo. Lucro.
Danylo Volokh
2
237 votos más en la respuesta y 62 en "no funciona hermano" 🤔 ¡Lo probé para obtener mi propia opinión y funciona perfecto!)
Daniel
165

utilizar:

editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
ungalcrys
fuente
20
Después de probar más de 5 otros enfoques, este fue el único que funcionó para mí (de una Viewsubclase)
William
13
Esta sugerencia conduce a que el teclado se repare, incluso cuando el campo pierde el foco.
hasta el
2
Sí, también funciona para mí y imm.showSoftInput()no funciona.
Spark.Bao
8
Si bien este método funciona, tiene un lado negativo, al salir de la aplicación con el botón de inicio (hardware) dejará el teclado en pantalla. Tendrá que presionar el botón de retorno (hardware) para ocultar el teclado y despreciarlo como inútil en su pantalla de inicio.
Adrien Horgnies
Otros enfoques no funcionaron para mí, este sí. gracias.
Iman Akbari
53

Esto funcionó para mí, gracias a ungalcrys

Mostrar teclado:

editText = (EditText)findViewById(R.id.myTextViewId);
editText.requestFocus();
InputMethodManager imm = (InputMethodManager)getSystemService(this.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);

Ocultar teclado:

InputMethodManager imm = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
Danilo Raspa
fuente
2
La única solución completa. Gracias.
korro
41

showSoftInput no estaba funcionando para mí en absoluto.

Pensé que necesitaba establecer el modo de entrada: android:windowSoftInputMode="stateVisible"(aquí en el componente Actividad en el manifiesto)

¡Espero que esto ayude!

vincebodi
fuente
55
Esto solo mostró el teclado cuando se inició la actividad.
William
1
Impresionante :) Intenté un montón de respuestas, pero solo con esto, pude hacerlo funcionar :) Muchas gracias.
Srikanth
respuesta muy subestimada
Avinash R
Respuesta perfecta. Funciona solo con "editText.requestFocus ()". Gracias.
AVJ
37
final EditText tb = new EditText(this);
tb.requestFocus();
tb.postDelayed(new Runnable() {
    @Override
    public void run() {
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.showSoftInput(tb, InputMethodManager.SHOW_IMPLICIT);
    }
}, 1000);
Kunal Bhatia
fuente
1
Tuve que hacer esto para que apareciera en onResume (). Sin la demora, no sucedería nada usando todas las soluciones descritas en este hilo.
FranticRock
1
Ahí está. Esa fue la respuesta que estaba buscando. Sin embargo, no necesita necesariamente un segundo retraso completo. Probé solo 150 milis, y eso también funcionó bien.
Rubberduck
1
¡Gracias! Esto funciona incluso para 0 ms ( tb.post({ showKeyboard(tb) })). Tenga en cuenta que necesitamos una vista EditText ( tb), no una vista fragmentaria.
CoolMind 01 de
16

Así es como se puede hacer una extensión de kotlin para mostrar y ocultar el teclado virtual:

fun View.showKeyboard() {
  this.requestFocus()
  val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  inputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

fun View.hideKeyboard() {
  val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}

Entonces puedes hacer esto:

editText.showKeyboard()
// OR
editText.hideKeyboard()
alvarlagerlof
fuente
esta es una mejor solución en comparación con el descanso
d-feverx
5

Recomiendo usar un LifecycleObserver que es parte de Handling Lifecycles with Lifecycle-Aware Components de Android Jetpack .

Quiero abrir y cerrar el teclado cuando aparece el Fragmento / Actividad. En primer lugar, defina dos funciones de extensión para EditText. Puede colocarlos en cualquier parte de su proyecto:

fun EditText.showKeyboard() {
    requestFocus()
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

fun EditText.hideKeyboard() {
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(this.windowToken, 0)
}

Luego defina un LifecycleObserver que abra y cierre el teclado cuando la Actividad / Fragmento alcance onResume()o onPause:

class EditTextKeyboardLifecycleObserver(private val editText: WeakReference<EditText>) :
    LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun openKeyboard() {
        editText.get()?.postDelayed({ editText.get()?.showKeyboard() }, 100)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun closeKeyboard() {
        editText.get()?.hideKeyboard()
    }
}

Luego agregue la siguiente línea a cualquiera de sus Fragmentos / Actividades, puede reutilizar el LifecycleObserver en cualquier momento. Por ejemplo, para un fragmento:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

    // inflate the Fragment layout

    lifecycle.addObserver(EditTextKeyboardLifecycleObserver(WeakReference(myEditText)))

    // do other stuff and return the view

}
Paul Spiesberger
fuente
4

Aquí está la clase KeyboardHelper para ocultar y mostrar el teclado

import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

/**
 * Created by khanhamza on 06-Mar-17.
 */

public class KeyboardHelper {
public static void hideSoftKeyboard(final Context context, final View view) {
    if (context == null) {
        return;
    }
    view.requestFocus();
    view.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}, 1000);
}

public static void hideSoftKeyboard(final Context context, final EditText editText) {
    editText.requestFocus();
    editText.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}, 1000);
}


public static void openSoftKeyboard(final Context context, final EditText editText) {
    editText.requestFocus();
    editText.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
}, 1000);
}
}
Hamza Khan
fuente
0

Primera forma :

    etPassword.post(() -> {
        etPassword.requestFocus();
        InputMethodManager manager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        manager.showSoftInput(etPassword, InputMethodManager.SHOW_IMPLICIT);
    });

Segunda forma :

En manifiesto:

    <activity
        android:name=".activities.LoginActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateVisible"/>

En codigo:

etPassword.requestFocus();
Hadi Note
fuente
0

Lo intenté de muchas maneras y no funciona, aunque no estoy seguro porque estoy usando una transición compartida de fragmento a actividad que contiene el texto de edición.

Por cierto, mi texto de edición también está envuelto en LinearLayout.

Agregué un ligero retraso para solicitar el enfoque y el siguiente código funcionó para mí: (Kotlin)

 et_search.postDelayed({
     editText.requestFocus()

     showKeyboard()
 },400) //only 400 is working fine, even 300 / 350, the cursor is not showing

showKeyboard ()

 val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
 imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
veeyikpong
fuente
0
editTxt.setOnFocusChangeListener { v, hasFocus ->
            val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            if (hasFocus) {
                imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
            } else {
                imm.hideSoftInputFromWindow(v.windowToken, 0)
            }
        }
Vasudev
fuente
-1

No pude obtener ninguna de estas respuestas para trabajar por su cuenta. La solución para mí fue combinarlos:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
editText.requestFocus();
imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);

No estoy seguro de por qué eso era necesario para mí; según los documentos, parece que cualquiera de los métodos debería haber funcionado por su cuenta.

mwu
fuente
Definitivamente esta no es una buena práctica. Tal vez, la transacción de Actividad o Fragmento estaba interviniendo con el teclado virtual o los indicadores del Método de entrada no se configuraron correctamente, pero de cualquier manera, esta solución no debe usarse.
Marcel Bro