Comment afficher le clavier logiciel lorsque edittext est focalisé
Je veux afficher automatiquement le clavier logiciel quand un EditText
est focalisé (si l'appareil n'a pas de clavier physique) et j'ai deux problèmes:
Lorsque mon {[1] } est affiché, mon
EditText
est focalisé mais le clavier n'est pas affiché, je dois cliquer à nouveau dessus pour afficher le clavier (il devrait être affiché lorsque monActivity
est affiché).Et quand je clique sur terminé sur le clavier, le clavier est décrit, mais le
EditText
reste concentré et y ne voulez pas (parce que mon montage est fait).
Pour reprendre, mon problème est d'avoir quelque chose de plus comme sur l'iPhone: qui maintient la synchronisation du clavier avec mon état EditText
(focalisé / non focalisé) et bien sûr ne présente pas de clavier logiciel s'il y en a un physique.
30 réponses
Pour forcer le clavier souple à apparaître, vous pouvez utiliser
EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);
Et pour supprimer le focus sur EditText
, malheureusement, vous devez avoir un mannequin View
pour saisir le focus.
J'espère que cela aide
Pour le fermer, vous pouvez utiliser
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
J'ai eu le même problème. Immédiatement après le changement de visibilité editText de GONE À VISIBLE, j'ai dû définir le focus et afficher le clavier logiciel. J'ai réalisé cela en utilisant le code suivant:
new Handler().postDelayed(new Runnable() {
public void run() {
// ((EditText) findViewById(R.id.et_find)).requestFocus();
//
EditText yourEditText= (EditText) findViewById(R.id.et_find);
// InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);
yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN , 0, 0, 0));
yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0));
}
}, 200);
Cela fonctionne pour moi avec un délai de 100 ms, mais a échoué sans délai ou avec seulement un délai de 1 ms.
Une partie commentée du code montre une autre approche, qui ne fonctionne que sur certains appareils. J'ai testé sur les versions OS 2.2 (émulateur), 2.2.1 (appareil réel) et 1.6 (émulateur).
Ce approche m'a sauvé beaucoup de douleur.
Pour faire apparaître le clavier, Utilisez
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
Cette méthode est plus fiable que d'appeler directement InputMethodManager.
Pour le fermer, utilisez
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Le code suivant est pillé à partir du code source 4.1 de Google pour SearchView. Semble fonctionner, bien sur les versions inférieures D'Android aussi bien.
private Runnable mShowImeRunnable = new Runnable() {
public void run() {
InputMethodManager imm = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(editText, 0);
}
}
};
private void setImeVisibility(final boolean visible) {
if (visible) {
post(mShowImeRunnable);
} else {
removeCallbacks(mShowImeRunnable);
InputMethodManager imm = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
}
}
Ensuite, le code suivant doit être ajouté Lors de la création du contrôle/de l'activité. (Dans mon cas, c'est un contrôle composite, plutôt qu'une activité).
this.editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
setImeVisibility(hasFocus);
}
});
Lorsque rien d'autre ne fonctionne, le forcer à être montré:
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
android:windowSoftInputMode="stateAlwaysVisible"
-> dans le fichier manifeste.
edittext.requestFocus();
-> dans le code.
Cela ouvrira le clavier logiciel sur lequel edit-text a le focus de la demande lorsque l'activité apparaît.
J'ai eu de la chance récemment dans certains cas simples avec le code dessous. Je n'ai pas fini tous les tests mais....
EditText input = (EditText) findViewById(R.id.Input);
input.requestFocus();
input.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN , 0, 0, 0));
input.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0));
Et presto le clavier apparaît.
, Vous pouvez essayer de forcer le clavier souple à apparaître, cela fonctionne pour moi:
...
dialog.show();
input.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
Pour masquer le clavier, utilisez celui-ci:
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Et pour afficher le clavier:
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Parfois, la réponse de raukodraug ne fonctionnera pas. Je l'ai fait de cette façon avec quelques essais et erreurs:
public static void showKeyboard(Activity activity) {
if (activity != null) {
activity.getWindow()
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
public static void hideKeyboard(Activity activity) {
if (activity != null) {
activity.getWindow()
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
Et la partieEditText :
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
hideKeyboard(getActivity());
} else {
showKeyboard(getActivity());
}
}
});
showSoftInput
ne travaillait pas pour moi du tout.
J'ai pensé que je devais définir le mode d'entrée: (ici dans le composant D'activité dans le manifeste)
android:windowSoftInputMode="stateVisible"
Pour le fragment, bien sûr son fonctionnement:
displayName = (EditText) view.findViewById(R.id.displayName);
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
J'ai tout combiné ici et pour moi ça marche:
public static void showKeyboardWithFocus(View v, Activity a) {
try {
v.requestFocus();
InputMethodManager imm = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
a.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
Croyez ou non mon problème avec le clavier logiciel a été résolu quand j'ai découvert que les animations D'activités peuvent désactiver le clavier logiciel. Lorsque vous appelez l'intention avec le
i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
Et
overridePendingTransition(0, 0);
Il peut masquer le clavier logiciel et il n'y a pas moyen de le montrer.
J'ai eu le même problème dans diverses situations différentes, et les solutions que j'ai trouvées fonctionnent dans certaines mais ne fonctionnent pas dans d'autres, alors voici une solution de combinaison qui fonctionne dans la plupart des situations que j'ai trouvées:
public static void showVirtualKeyboard(Context context, final View view) {
if (context != null) {
final InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
view.clearFocus();
if(view.isShown()) {
imm.showSoftInput(view, 0);
view.requestFocus();
} else {
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
view.post(new Runnable() {
@Override
public void run() {
view.requestFocus();
imm.showSoftInput(view, 0);
}
});
view.removeOnAttachStateChangeListener(this);
}
@Override
public void onViewDetachedFromWindow(View v) {
view.removeOnAttachStateChangeListener(this);
}
});
}
}
}
Extrait de Code . . .
public void hideKeyboard(Context activityContext){
InputMethodManager imm = (InputMethodManager)
activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);
//android.R.id.content ( http://stackoverflow.com/a/12887919/2077479 )
View rootView = ((Activity) activityContext)
.findViewById(android.R.id.content).getRootView();
imm.hideSoftInputFromWindow(rootView.getWindowToken(), 0);
}
public void showKeyboard(Context activityContext, final EditText editText){
final InputMethodManager imm = (InputMethodManager)
activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (!editText.hasFocus()) {
editText.requestFocus();
}
editText.post(new Runnable() {
@Override
public void run() {
imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
}
});
}
Ça a marché pour moi. Vous pouvez essayer avec cela aussi pour montrer le clavier:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Il suffit d'ajouter android: windowSoftInputMode= "stateHidden" dans le fichier manifeste...
final InputMethodManager keyboard = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
editText.post(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
});
Toutes les solutions données ci-dessus (inputmethodmanager interaction dans OnFocusChangeListener.onfocuschange écouteur attaché à votre EditText fonctionne bien si vous avez une seule édition dans l'activité.
Dans mon cas, j'ai deux modifications.
private EditText tvX, tvY;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tvX.setOnFocusChangeListener(this);
tvY.setOnFocusChangeListener(this);
@Override
public void onFocusChange(View v, boolean hasFocus) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if(tvX.hasFocus() || tvY.hasFocus()) {
imm.showSoftInput(v, 0);
} else {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
};
J'ai observé que onFocusChange est déclenché pour tvX avec hasFocus=true (clavier montré) mais ensuite pour tvY avec hasFocus=true (clavier caché). En fin de compte, aucun clavier n'était visible.
Solution générale devrait avoir une instruction correcte Si "afficher le clavier si le texte EditText a le focus"
Dans votre section onResume () de l'activité, vous pouvez appeler la méthode bringKeyboard ();
onResume() {
EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
bringKeyboard(yourEditText);
}
protected boolean bringKeyboard(EditText view) {
if (view == null) {
return false;
}
try {
// Depending if edittext has some pre-filled values you can decide whether to bring up soft keyboard or not
String value = view.getText().toString();
if (value == null) {
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
return true;
}
} catch (Exception e) {
Log.e(TAG, "decideFocus. Exception", e);
}
return false;
}
Dans votre manifeste:
android:windowSoftInputMode="stateAlwaysVisible"
- initialement lancé clavier.
android:windowSoftInputMode="stateAlwaysHidden"
- clavier initialement caché.
J'aime aussi utiliser "adjustPan"
car lorsque le clavier se lance, l'écran s'ajuste automatiquement.
<activity
android:name="YourActivity"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"/>
J'ai découvert un comportement étrange, puisque dans une de mes applications, le clavier logiciel s'affichait automatiquement en entrant dans l'activité (il y a un editText.requestFocus () dans onCreate).
En creusant plus loin, j'ai découvert que c'était parce qu'il y avait un ScrollView autour de la mise en page. Si je supprime le ScrollView, le comportement est comme décrit dans l'énoncé de problème d'origine: ce n'est qu'en cliquant sur le editText déjà ciblé que le clavier logiciel apparaît.
Si cela ne fonctionne pas pour vous, essayez de mettre dans un ScrollView - c'est inoffensif de toute façon.
J'ai eu un problème similaire en utilisant des animations. J'ai donc mis un écouteur d'animation pour m'assurer que attend que l'animation se termine avant d'essayer de demander un accès au clavier sur le edittext affiché.
bottomUp.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (textToFocus != null) {
// Position cursor at the end of the text
textToFocus.setSelection(textToFocus.getText().length());
// Show keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(textToFocus, InputMethodManager.SHOW_IMPLICIT);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
Je suis d'accord avec raukodraug à cet effet en utilisant dans un swithview vous devez demander / clear focus comme ceci:
final ViewSwitcher viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
final View btn = viewSwitcher.findViewById(R.id.address_btn);
final View title = viewSwitcher.findViewById(R.id.address_value);
title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewSwitcher.showPrevious();
btn.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(btn, InputMethodManager.SHOW_IMPLICIT);
}
});
// EditText affiche le titre evenement click
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
btn.clearFocus();
viewSwitcher.showNext();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(btn.getWindowToken(), 0);
// Enregistre l'adresse.
addAddress(view);
}
});
Cordialement.
En utilisant Xamarin, cela fonctionne pour moi dans un Fragment:
using Android.Views.InputMethods;
using Android.Content;
...
if ( _txtSearch.RequestFocus() ) {
var inputManager = (InputMethodManager) Activity.GetSystemService( Context.InputMethodService );
inputManager.ShowSoftInput( _txtSearch, ShowFlags.Implicit );
}
J'ai fait cette classe d'aide. Il suffit de passer le contexte et la vue que vous souhaitez mettre au point et afficher le clavier et après masquer le clavier. J'espère que cela Aide.
public class FocusKeyboardHelper {
private View view;
private Context context;
private InputMethodManager imm;
public FocusKeyboardHelper(Context context, View view){
this.view = view;
this.context = context;
imm = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE);
}
public void focusAndShowKeyboard(){
view.requestFocus();
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
public void hideKeyBoard(){
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
void requestFocus(View editText, Activity activity)
{
try {
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
Ajouter cette ligne aussi ne pas oublier
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
Vous pouvez également créer une extension personnalisée de EditText qui sait ouvrir le clavier logiciel lorsqu'il reçoit le focus. C'est ce que j'ai fini par faire. Voici ce qui a fonctionné pour moi:
public class WellBehavedEditText extends EditText {
private InputMethodManager inputMethodManager;
private boolean showKeyboard = false;
public WellBehavedEditText(Context context) {
super(context);
this.initializeWellBehavedEditText(context);
}
public WellBehavedEditText(Context context, AttributeSet attributes) {
super(context, attributes);
this.initializeWellBehavedEditText(context);
}
public WellBehavedEditText(Context context, AttributeSet attributes, int defStyleAttr) {
super(context, attributes, defStyleAttr);
this.initializeWellBehavedEditText(context);
}
public WellBehavedEditText(Context context, AttributeSet attributes, int defStyleAttr, int defStyleRes) {
super(context, attributes, defStyleAttr, defStyleRes);
this.initializeWellBehavedEditText(context);
}
private void initializeWellBehavedEditText(Context context) {
this.inputMethodManager = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
final WellBehavedEditText editText = this;
this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if(showKeyboard) {
showKeyboard = !(inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_FORCED));
}
}
});
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if(!focused) this.showKeyboard = false;
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
boolean result = super.requestFocus(direction, previouslyFocusedRect);
this.showKeyboard = true;
final WellBehavedEditText self = this;
this.post(new Runnable() {
@Override
public void run() {
showKeyboard = !(inputMethodManager.showSoftInput(self, InputMethodManager.SHOW_FORCED));
}
});
return result;
}
}