Comment puis-je définir le focus (et afficher le clavier) sur mon EditText par programmation

187

J'ai une mise en page qui contient des vues comme celle-ci:

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

Comment puis-je définir le focus (afficher le clavier) sur mon EditTextprogramme?

J'ai essayé cela et cela ne fonctionne que lorsque je lance mon Activitynormalement, mais lorsque je le lance dans un TabHost, cela ne fonctionne pas.

txtSearch.setFocusableInTouchMode(true);
txtSearch.setFocusable(true);
txtSearch.requestFocus();
Houcine
la source

Réponses:

367

Essaye ça:

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
la source
5
cela ne fonctionne que lorsque je lance mon activité normalement, mais lorsque je lance mon activité sur un TabHost, cela ne fonctionne pas,
Houcine
29
Cela ne marche pas. Celui-ci fonctionne pour moi InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput (InputMethodManager.SHOW_FORCED, 0);
Günay Gültekin
7
"Cela ne fonctionne pas frère". Dans certains cas, vous devez appeler ce code de manière asynchrone à partir de postDelayed (). J'ai eu un cas où j'ai dû ouvrir le clavier après que l'utilisateur ait appuyé sur "OK" dans la boîte de dialogue. Et quand le dialogue se fermait, il perturbait le focus. J'ai donc appelé le code ci-dessus à partir de postDelayed (). Il s'est exécuté après la fermeture du dialogue. Profit.
Danylo Volokh
2
237 votes pour la réponse et 62 pour "ça ne marche pas mon frère" 🤔 Je l'ai testé pour me faire ma propre opinion et ça fonctionne parfaitement!)
Daniel
1
Juste pour partager l'expérience: je viens d'ajouter le code à quatre fragments différents dans mon projet d'application actuel. Avec les trois premiers fragments, le code fonctionnait parfaitement. Avec le dernier fragment, aucun clavier n'a été affiché jusqu'à ce que je lance le code à partir de onViewCreated avec un délai de 100 ms en utilisant Kotlin Coroutines.
Nantoka
168

utilisation:

editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
ungalcrys
la source
20
Après avoir essayé plus de 5 autres approches, c'est la seule qui a fonctionné pour moi (d'une Viewsous - classe)
William
14
Cette suggestion conduit à la correction du clavier, même lorsque le champ perd le focus.
jusqu'au
2
oui, ça marche aussi pour moi et imm.showSoftInput()ça ne marche pas.
Spark.Bao
8
Bien que cette méthode fonctionne, elle a un inconvénient: quitter l'application avec le bouton d'accueil (matériel) laissera le clavier sur l'écran. Vous devrez appuyer sur le bouton de retour (matériel) pour masquer le clavier, le mépriser étant inutile sur votre écran d'accueil.
Adrien Horgnies
D'autres approches n'ont pas fonctionné pour moi, celle-ci a fonctionné. Merci.
Iman Akbari
53

Cela a fonctionné pour moi, grâce aux ungalcrys

Afficher le clavier:

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

Masquer le clavier:

InputMethodManager imm = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
Danilo Raspa
la source
2
La seule solution complète. Merci.
korro
41

showSoftInput ne fonctionnait pas du tout pour moi.

J'ai pensé que j'avais besoin de définir le mode d'entrée: android:windowSoftInputMode="stateVisible"(ici dans le composant Activité du manifeste)

J'espère que cette aide!

Vincebodi
la source
5
Cela montrait juste le clavier au début de l'activité.
William
1
Génial :) J'ai essayé un tas de réponses mais seulement avec ça, je pourrais le faire fonctionner :) Merci beaucoup.
Srikanth le
réponse très sous-estimée
Avinash R
Réponse parfaite. Fonctionne uniquement avec "editText.requestFocus ()". Merci.
AVJ
40
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
la source
1
J'ai dû le faire pour qu'il apparaisse dans onResume (). Sans ce délai, rien ne se passerait en utilisant chaque solution unique décrite dans ce fil.
FranticRock
1
Le voilà. C'était la réponse que je cherchais. Cependant, vous n'avez pas nécessairement besoin d'un deuxième délai entier. J'ai essayé seulement 150 millis, et cela a bien fonctionné aussi.
Rubberduck
2
Merci! Cela fonctionne même pendant 0 ms ( tb.post({ showKeyboard(tb) })). Notez que nous avons besoin d'une vue EditText ( tb), pas d'une vue fragmentée.
CoolMind
19

Voici comment créer une extension kotlin pour afficher et masquer le clavier virtuel:

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

Ensuite, vous pouvez simplement faire ceci:

editText.showKeyboard()
// OR
editText.hideKeyboard()
alvarlagerlof
la source
2
c'est une meilleure solution par rapport au repos
d-feverx
5

Je recommande d'utiliser un LifecycleObserver qui fait partie de la gestion des cycles de vie avec les composants Lifecycle-Aware d' Android Jetpack .

Je souhaite ouvrir et fermer le clavier lorsque le fragment / l'activité apparaît. Tout d'abord, définissez deux fonctions d'extension pour EditText. Vous pouvez les placer n'importe où dans votre projet:

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

Définissez ensuite un LifecycleObserver qui ouvre et ferme le clavier lorsque l'activité / fragment atteint 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()
    }
}

Ajoutez ensuite la ligne suivante à l'un de vos fragments / activités, vous pouvez réutiliser le LifecycleObserver à tout moment. Par exemple pour un fragment:

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
la source
4

Voici la classe KeyboardHelper pour cacher et afficher le clavier

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
la source
1

J'ai essayé la meilleure réponse de David Merriman et cela n'a pas non plus fonctionné dans mon cas. Mais j'ai trouvé la suggestion d'exécuter ce code retardée ici et cela fonctionne comme un charme.

val editText = view.findViewById<View>(R.id.settings_input_text)

editText.postDelayed({
    editText.requestFocus()

    val imm = context.getSystemService(INPUT_METHOD_SERVICE) as? InputMethodManager
    imm?.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
}, 100)
LeFrosch
la source
0

Première manière :

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

Deuxième manière :

Dans le manifeste:

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

Dans du code:

etPassword.requestFocus();
Hadi Note
la source
0

J'ai essayé de nombreuses façons et cela ne fonctionne pas, je ne suis pas sûr que ce soit parce que j'utilise la transition partagée du fragment à l'activité contenant le texte d'édition.

Btw mon edittext est également enveloppé dans LinearLayout.

J'ai ajouté un léger retard pour demander la mise au point et le code ci-dessous a fonctionné pour moi: (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
la source
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
la source
-1

Je n'ai pas réussi à faire fonctionner toutes ces réponses par elles-mêmes. La solution pour moi était de les combiner:

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

Je ne sais pas pourquoi cela était nécessaire pour moi - selon la documentation, il semble que l'une ou l'autre méthode aurait dû fonctionner seule.

mwu
la source
Ce n'est certainement pas une bonne pratique. Peut-être que la transaction d'activité ou de fragment intervenait avec le clavier virtuel ou que les indicateurs de méthode de saisie n'étaient pas correctement définis, mais dans tous les cas, cette solution ne doit pas être utilisée.
Marcel Bro