Como posso definir o foco (e exibir o teclado) no meu EditText programaticamente

180

Eu tenho um layout que contém algumas visualizações como esta:

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

Como posso definir o foco (exibir o teclado) no meu EditTextprogramaticamente?

Eu tentei isso e só funciona quando inicio o meu Activitynormalmente, mas quando inicio em um TabHost, não funciona.

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

Respostas:

353

Tente o seguinte:

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
fonte
Atualizado com o código para forçar o teclado a ser exibido a partir desta resposta: stackoverflow.com/questions/5105354/…
David Merriman
5
ele só funciona quando eu lançar minha atividade normalmente, mas quando eu lançar minha atividade em um TabHost, ele não funciona,
Houcine
27
Isso não funciona. Este funciona para mim InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput (InputMethodManager.SHOW_FORCED, 0);
Günay Gültekin
5
"Isso não funciona, irmão". Em alguns casos, você precisa chamar esse código de forma assíncrona a partir de postDelayed (). Eu tive um caso quando tive que abrir o teclado depois que o usuário pressionou "OK" na caixa de diálogo. E quando o diálogo estava sendo fechado, estava mexendo com o foco. Então, eu chamei o código acima de postDelayed (). Foi executado após o fechamento do diálogo. Lucro.
Danylo Volokh
2
237 votos úteis na resposta e 62 em "não funciona, irmão" 🤔 Eu testei para obter sua própria opinião e funciona perfeitamente!) #
Daniel Daniel
165

usar:

editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
ungalcrys
fonte
20
Depois de tentar mais de 5 outras abordagens, este foi o único que trabalhou para mim (a partir de uma Viewsubclasse)
William
13
Essa sugestão leva à correção do teclado, mesmo quando o campo perde o foco.
até
2
sim, funciona para mim também e imm.showSoftInput()não funciona.
Spark.Bao
8
Embora esse método funcione, ele tem o lado negativo, sair do aplicativo com o botão home (hardware) deixará o teclado na tela. Você terá que pressionar o botão de retorno (hardware) para ocultar o teclado, apesar de ser inútil na tela inicial.
Adrien Horgnies 07/07
Outras abordagens não funcionaram para mim, esta funcionou. obrigado.
Iman Akbari
53

Isso funcionou para mim, graças 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
fonte
2
A única solução completa. Obrigado.
Korro
41

showSoftInput não estava funcionando para mim.

Imaginei que precisava definir o modo de entrada: android:windowSoftInputMode="stateVisible"(aqui no componente Activity no manifesto)

Espero que esta ajuda!

vincebodi
fonte
5
Isso apenas mostrou o teclado quando a atividade foi iniciada.
William
1
Impressionante :) Tentei um monte de respostas, mas só com isso, eu poderia fazê-lo funcionar :) Muito obrigado.
Srikanth
resposta muito subestimada
Avinash R:
Resposta perfeita. Funciona apenas com "editText.requestFocus ()". Obrigado.
AVJ 19/11/19
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
fonte
1
Eu tive que fazer isso para que ele aparecesse em onResume (). Sem o atraso, nada aconteceria usando todas as soluções descritas neste segmento.
FranticRock
1
Aí está. Essa era a resposta que eu estava procurando. Porém, você não precisa necessariamente de um segundo atraso inteiro. Eu tentei apenas 150 milis e isso funcionou bem também.
precisa
1
Obrigado! Isso funciona mesmo para 0 ms ( tb.post({ showKeyboard(tb) })). Observe que precisamos de uma visão EditText ( tb), não uma visão fragmentada.
CoolMind 01/07/19
16

Aqui está como uma extensão kotlin para mostrar e ocultar o teclado virtual pode ser feita:

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

Então você pode fazer isso:

editText.showKeyboard()
// OR
editText.hideKeyboard()
alvarlagerlof
fonte
esta é uma solução melhor em comparação com o resto
d-feverx 23/06
5

Eu recomendo o uso de um LifecycleObserver que faz parte do Manipulando Ciclos de Vida com Componentes Reconhecidos pelo Ciclo de Vida do Android Jetpack .

Quero abrir e fechar o teclado quando o fragmento / atividade aparecer. Primeiro, defina duas funções de extensão para o EditText. Você pode colocá-los em qualquer lugar do seu projeto:

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

Em seguida, defina um LifecycleObserver que abra e feche o teclado quando a Atividade / Fragmento atingir onResume()ou 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()
    }
}

Em seguida, adicione a seguinte linha a qualquer um dos seus Fragmentos / Atividades. Você pode reutilizar o LifecycleObserver a qualquer momento. Por exemplo, para um 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
fonte
4

Aqui está a classe KeyboardHelper para ocultar e mostrar o 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
fonte
0

Primeira maneira :

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

Segunda maneira :

Em manifesto:

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

Em código:

etPassword.requestFocus();
Hadi Note
fonte
0

Tentei de várias maneiras e não está funcionando, não tenho certeza porque estou usando a transição compartilhada de fragmento para atividade que contém o texto de edição.

Btw meu edittext também é envolto em LinearLayout.

Eu adicionei um pequeno atraso para solicitar o foco e o código abaixo funcionou para mim: (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
fonte
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
fonte
-1

Não consegui que nenhuma dessas respostas funcionasse por conta própria. A solução para mim foi combiná-los:

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

Não sei por que isso foi necessário para mim - de acordo com os documentos, parece que qualquer um dos métodos deveria ter funcionado por conta própria.

mwu
fonte
Definitivamente, essa não é uma boa prática. Talvez a transação de Atividade ou Fragmento esteja interferindo no teclado virtual ou os sinalizadores de Método de Entrada não foram definidos corretamente, mas, de qualquer forma, esta solução não deve ser usada.
Marcel Bro