Android: afficher le clavier souple automatiquement lorsque l'accent est mis sur un texte D'édition
je montre une boîte de saisie en utilisant AlertDialog
. Le EditText
dans le dialogue lui-même est automatiquement focalisé lorsque j'appelle AlertDialog.show()
, mais le clavier souple n'est pas automatiquement affiché.
Comment faire apparaître automatiquement le clavier souple lorsque la boîte de dialogue est affichée? (et il n'y a pas de physique/matériel clavier). Tout comme lorsque j'appuie sur le bouton de recherche pour lancer la recherche globale, le clavier souple s'affiche automatiquement.
24 réponses
vous pouvez créer un auditeur focus sur le EditText
sur le AlertDialog
, puis obtenir le AlertDialog
's Window
. De là, vous pouvez faire apparaître le clavier souple en appelant setSoftInputMode
.
final AlertDialog dialog = ...;
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
pour afficher l'utilisation du clavier:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
Pour masquer le clavier:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(),0);
vous pouvez demander un clavier souple juste après avoir créé le dialogue (test sur SDK - r20)
// create dialog
final AlertDialog dialog = ...;
// request keyboard
dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
j'ai eu le même problème et résolu avec le code suivant. Je ne sais pas comment il se comportera sur un téléphone avec un clavier matériel.
// TextEdit
final EditText textEdit = new EditText(this);
// Builder
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Enter text");
alert.setView(textEdit);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String text = textEdit.getText().toString();
finish();
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
// Dialog
AlertDialog dialog = alert.create();
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
}
});
dialog.show();
j'ai trouvé cet exemple http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html . Ajouter le code suivant juste avant alert.show()
.
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
<activity
...
android:windowSoftInputMode="stateVisible" >
</activity>
ou
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
extraits de code d'autres réponses fonctionnent, mais il n'est pas toujours évident où les placer dans le code, surtout si vous utilisez un AlertDialog.Builder
et suivi le tutoriel de dialogue officiel parce qu'il n'utilise pas final AlertDialog ...
ou alertDialog.show()
.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
est préférable à
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
parce que SOFT_INPUT_STATE_ALWAYS_VISIBLE cache le clavier si le focus s'éloigne de L'EditText, où SHOW_FORCED maintiendra le clavier affiché jusqu'à ce qu'il soit explicitement rejeté, même si l'utilisateur retourne sur l'écran d'accueil ou affiche les applications récentes.
ci-dessous est le code de travail pour un AlertDialog créé en utilisant une mise en page personnalisée avec un texte D'édition défini en XML. Il permet également au clavier d'avoir une touche "go" et de déclencher le bouton positif.
alert_dialog.xml:
<RelativeLayout
android:id="@+id/dialogRelativeLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- android:imeOptions="actionGo" sets the keyboard to have a "go" key instead of a "new line" key. -->
<!-- android:inputType="textUri" disables spell check in the EditText and changes the "go" key from a check mark to an arrow. -->
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="16dp"
android:imeOptions="actionGo"
android:inputType="textUri"/>
</RelativeLayout>
AlertDialog.Java:
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
public class CreateDialog extends AppCompatDialogFragment {
// The public interface is used to send information back to the activity that called CreateDialog.
public interface CreateDialogListener {
void onCreateDialogCancel(DialogFragment dialog);
void onCreateDialogOK(DialogFragment dialog);
}
CreateDialogListener mListener;
// Check to make sure that the activity that called CreateDialog implements both listeners.
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (CreateDialogListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement CreateDialogListener.");
}
}
// onCreateDialog requires @NonNull.
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
LayoutInflater customDialogInflater = getActivity().getLayoutInflater();
// Setup dialogBuilder.
alertDialogBuilder.setTitle(R.string.title);
alertDialogBuilder.setView(customDialogInflater.inflate(R.layout.alert_dialog, null));
alertDialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mListener.onCreateDialogCancel(CreateDialog.this);
}
});
alertDialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mListener.onCreateDialogOK(CreateDialog.this);
}
});
// Assign the resulting built dialog to an AlertDialog.
final AlertDialog alertDialog = alertDialogBuilder.create();
// Show the keyboard when the dialog is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
// We need to show alertDialog before we can setOnKeyListener below.
alertDialog.show();
EditText editText = (EditText) alertDialog.findViewById(R.id.editText);
// Allow the "enter" key on the keyboard to execute "OK".
editText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter" button, select the PositiveButton "OK".
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Trigger the create listener.
mListener.onCreateDialogOK(CreateDialog.this);
// Manually dismiss alertDialog.
alertDialog.dismiss();
// Consume the event.
return true;
} else {
// If any other key was pressed, do not consume the event.
return false;
}
}
});
// onCreateDialog requires the return of an AlertDialog.
return alertDialog;
}
}
jetez un coup d'oeil à cette discussion qui gère manuellement cacher et montrer L'EMI. Cependant, mon sentiment est que si un EditText
focalisé n'apporte pas l'IME vers le haut, c'est parce que vous appelez AlertDialog.show()
dans votre OnCreate()
ou une autre méthode qui est évoqué avant que l'écran est réellement présenté. Le déplacer à OnPostResume()
devrait le corriger dans ce cas je crois.
Permettez-moi de pointer quelques informations supplémentaires à la solution de yuku, parce que j'ai eu du mal à obtenir ce travail! Comment puis-je obtenir L'objet AlertDialog de mon AlertDialog.Builder? Eh bien, c'est le résultat de mon alert.show()
exécution:
final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
final EditText input = new EditText(getActivity());
alert.setView(input);
// do what you need, like setting positive and negative buttons...
final AlertDialog dialog = alert.show();
input.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
Eh bien, c'est un assez vieux post, Il ya encore quelque chose à ajouter.
ce sont 2 méthodes simples qui m'aident à garder le clavier sous contrôle et ils fonctionnent tout simplement parfait:
Afficher le clavier
public void showKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View v = getCurrentFocus();
if (v != null)
imm.showSoftInput(v, 0);
}
Cacher le clavier
public void hideKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View v = getCurrentFocus();
if (v != null)
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
Oui, vous pouvez le faire avec setOnFocusChangeListener
il va vous aider.
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
});
Si quelqu'un est arriver:
ne peut pas faire de référence statique à la méthode non statique getSystemService (String) de L'activité de type
essayez d'ajouter context à l'appel getSystemService.
Donc
InputMethodManager imm =
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
la question initiale concerne les dialogues et mon texte D'édition est sur une vue régulière. Quoi qu'il en soit, je pense que cela devrait fonctionner pour la plupart d'entre vous aussi. Voici donc ce qui fonctionne pour moi (la méthode la mieux notée suggérée ci-dessus n'a rien fait pour moi). Voici un Éditview personnalisé qui fait cela (le sous-classement n'est pas nécessaire, mais je l'ai trouvé pratique pour mes besoins car je voulais également saisir le focus lorsque la vue devient visible).
c'est en fait en grande partie la même chose que les tidbecks réponse. En fait, je n'ai pas remarqué sa réponse du tout car il avait zéro voix. Puis j'étais sur le point de commenter son post, mais ça aurait été trop long, donc j'ai fini par faire ce post de toute façon. tidbeck fait remarquer qu'il n'est pas certain de la façon dont cela fonctionne avec les appareils ayant des claviers. Je peux confirmer que le comportement semble être exactement le même dans les deux cas. Cela étant tel que sur le mode portrait le clavier de logiciel apparaît et sur le paysage il ne fait pas. Ayant le clavier physique glissé ou non ne fait aucune différence sur mon téléphone.
parce que, personnellement, j'ai trouvé le comportement un peu bizarre que j'ai choisi d'utiliser: InputMethodManager.SHOW_FORCED
. Cela fonctionne comme je le voulais travailler. Le clavier devient visible quelle que soit l'orientation, cependant, au moins sur mon appareil il n'apparaît pas si le clavier matériel a été glissé.
import android.app.Service;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
public class BringOutTheSoftInputOnFocusEditTextView extends EditText {
protected InputMethodManager inputMethodManager;
public BringOutTheSoftInputOnFocusEditTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public BringOutTheSoftInputOnFocusEditTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BringOutTheSoftInputOnFocusEditTextView(Context context) {
super(context);
init();
}
private void init() {
this.inputMethodManager = (InputMethodManager)getContext().getSystemService(Service.INPUT_METHOD_SERVICE);
this.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
BringOutTheSoftInputOnFocusEditTextView.this.inputMethodManager.showSoftInput(BringOutTheSoftInputOnFocusEditTextView.this, InputMethodManager.SHOW_FORCED);
}
}
});
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (visibility == View.VISIBLE) {
BringOutTheSoftInputOnFocusEditTextView.this.requestFocus();
}
}
}
le problème semble être que depuis l'endroit où vous entrez le texte est caché initialement (ou imbriqué ou quelque chose), AlertDialog met automatiquement le drapeau WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
ou WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
de sorte que les choses ne déclenchent pas une entrée douce pour apparaître.
ajouter ce qui suit:
(...)
// Create the dialog and show it
Dialog dialog = builder.create()
dialog.show();
// After show (this is important specially if you have a list, a pager or other view that uses a adapter), clear the flags and set the soft input mode
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
essayer et utiliser:
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
pour montrer le clavier, pour moi, j'ai dû faire ce qui suit
Android TextField : focus + une entrée par programme
essentiellement la solution est la suivante
@Override
public void onResume() {
super.onResume();
//passwordInput.requestFocus(); <-- that doesn't work
passwordInput.postDelayed(new ShowKeyboard(), 325); //250 sometimes doesn't run if returning from LockScreen
}
où ShowKeyboard
est
private class ShowKeyboard implements Runnable {
@Override
public void run() {
passwordInput.setFocusableInTouchMode(true);
//passwordInput.requestFocusFromTouch(); //this gives touch event to launcher in background -_-
passwordInput.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
}
}
après une entrée réussie, je m'assure également de cacher le clavier
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(getView().getWindowToken(), 0);
c'est un bon échantillon pour vous:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:id="@+id/scrollID"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:weightSum="1" >
<EditText
android:id="@+id/txtInpuConversation"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:hint="@string/edt_Conversation" >
<requestFocus />
</EditText>
<Button
android:id="@+id/btnSend"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="@string/btn_Conversation" />
</LinearLayout>
</LinearLayout>
pourquoi cette réponse-Parce que la solution ci-dessus affichera votre clavier, mais il ne disparaîtra pas si vous cliquez n'importe où d'autre que EditText
. Donc vous devez faire quelque chose pour faire disparaître le keybaord quand EditText
perd sa concentration.
vous pouvez y parvenir en suivant les étapes suivantes:
-
rendez la vue parente(vue du contenu de votre activité) cliquable et focalisable en ajoutant les attributs suivants
android:clickable="true" android:focusableInTouchMode="true"
-
mettre en Œuvre un hideKeyboard() la méthode
public void hideKeyboard(View view) { InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_IMPLICIT_ONLY ); }
-
enfin, définissez le onFocusChangeListener de votre texte d'édition.
edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { hideKeyboard(v); } } });
C'est un peu délicat. J'ai fait de cette façon et cela a fonctionné.
1.Au premier appel pour cacher l'entrée douce de la fenêtre. Cela masquera l'entrée soft si le clavier soft est visible ou ne fera rien s'il ne l'est pas.
2.Afficher votre dialogue
3.Puis il suffit d'appeler à bascule douce d'entrée.
code:
InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
//hiding soft input
inputManager.hideSoftInputFromWindow(findViewById(android.R.id.content).getWindowToken(), 0);
//show dialog
yourDialog.show();
//toggle soft input
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.SHOW_IMPLICIT);
Essayez cette
SomeUtils.java
public static void showKeyboard(Activity activity, boolean show) { InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); if(show) inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); else inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0); }
mettez ces méthodes dans votre classe Util et utilisez-les n'importe où.
Kotlin
fun hideKeyboard(activity: Activity) {
val view = activity.currentFocus
val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
private fun showKeyboard(activity: Activity) {
val view = activity.currentFocus
val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
Java
public static void hideKeyboard(Activity activity) {
View view = activity.getCurrentFocus();
InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert methodManager != null && view != null;
methodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
private static void showKeyboard(Activity activity) {
View view = activity.getCurrentFocus();
InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert methodManager != null && view != null;
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
Comme horkavlna , a écrit,
basculer
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
et cacher clavier
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
méthodes de travail. Mais show les variantes ne fonctionnent pas dans mon cas. Ainsi, dans onCreate()
j'ai mis hideKeyboard(editText);
puis dans onStart()
j'écris toggleKeyboard(editText);
et dans onStop()
j'écris hideKeyboard(editText);
.
il y a trois problèmes:
1) quand une application commence avec l'écran éteint, il cachera le clavier,
2) chaque fois que vous allumez l'écran il affichera le clavier,
3) après la fin de l'application, vous pouvez voir le clavier dans L'écran principal Android.
après plusieurs tests j'ai retiré ces méthodes et dans AndroidManifest
dans activity
tags écrit android:windowSoftInputMode="stateVisible"
ou android:windowSoftInputMode="stateAlwaysHidden"
.
j'ai créé de belles fonctions d'extension kotlin-esqe incase n'importe qui est intéressé
fun Activity.hideKeyBoard() {
val view = this.currentFocus
val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
fun Activity.showKeyboard() {
val view = this.currentFocus
val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Je l'appelle onCreate() pour afficher le clavier automatiquement, quand je suis entré dans l'activité.