web-dev-qa-db-fra.com

Appuyez sur edittext extérieur pour perdre le focus

Je veux juste que lorsque vous cliquez en dehors du "edittext", le focus et le clavier soient automatiquement perdus. Pour le moment, si je clique sur le "edittext", il se concentre mais je dois appuyer sur le bouton de retour pour se décaler. 

35
JustCurious

@woodshy a la solution pour cacher le clavier, mais peut-être que mettre le code dans onClick n'est pas aussi bon que de le mettre dans onFocusChanged. Pour le forcer à perdre le focus, vous devez définir l'objet vers lequel vous souhaitez transférer le focus, dans son fichier XML: 

Android:focusable="true"
Android:focusableInTouchMode ="true"
18
lynnyilu

Pour résoudre ce problème, vous devez d'abord utiliser setOnFocusChangeListener de cet Edittext 

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    Log.d("focus", "focus loosed");
                    // Do whatever you want here
                } else {
                    Log.d("focus", "focused");
                }
            }
        });

ensuite, vous devez remplacer dispatchTouchEvent dans l'activité contenant Edittext, voir le code ci-dessous.

@Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if ( v instanceof EditText) {
                Rect outRect = new Rect();
                v.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                    Log.d("focus", "touchevent");
                    v.clearFocus();
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
        }
        return super.dispatchTouchEvent(event);
    }

Maintenant, que se passera-t-il lorsqu'un utilisateur cliquera à l'extérieur alors, d'abord ce dispatchTouchEvent sera appelé, puis le focus de l'editext sera effacé; maintenant, votre OnFocusChangeListener sera appelé si ce focus a été modifié. Vous pouvez maintenant faire tout ce que vous voulez faire. , esperons que ça marche :)

17
Sudhanshu Gaur

Supposons que votre EditText soit placé sur une disposition linéaire ou un autre groupe de vues. Ensuite, vous devez rendre ce conteneur cliquable, focusable et focusableInTouchMode. Après cela, définissez onClickListener sur ce conteneur avec le code suivant dans la méthode onClick Override: 

@Override
public void onClick(View view) {
    InputMethodManager imm = (InputMethodManager) view.getContext()
            .getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
14
woodshy

J'ai donc cherché un peu, et aucune autre solution n'était exactement ce que je cherchais. À mon avis, le focus se comporte étrangement sur les vues EditText.

Ce que j'ai fait était ...

  1. Assurez-vous que la vue racine est un RelativeLayout

  2. Ajoutez une disposition de superposition sur la zone qui fera disparaître le clavier, mais pas le texte d'édition. Quelque chose comme ci-dessous:

Dans mon cas, le EditText était dans un conteneur au bas de l'écran. donc ça couvrait tout le reste.

  1. Avoir une méthode qui ressemble un peu à celle-ci:
 private void hideKeyboard () {
 final InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); 
 imm.hideSoftInputFromWindow (editText.getWindowToken (), 0); 
 keyboardOverlay.setVisibility (View.GONE); 
 editText.clearFocus (); 
 } 
  1. Appelez maintenant cette méthode sur le clic de la superposition que vous avez créée.

  2. Ce que nous voulons maintenant, c’est de rendre la superposition visible lorsque vous appuyez sur le editText. Vous ne pouvez pas utiliser l'événement onFocus (du moins, je n'ai pas réussi à le faire fonctionner ...). Ce que j'ai fait, c'est donc que j'ai géré l'événement onTouch.

.________ . editText.requestFocus (); 
 return false; 
} 
}); 

Le requestFocus () ici est de ne pas remplacer l'événement de focus avec le onTouch.

Petit conseil, lorsque vous essayez ceci, vous pouvez ajouter une couleur de fond à la superposition pour voir exactement ce qui se passe.

J'espère que ça marche pour toi!

1
Charles

Vous pouvez y parvenir en procédant comme suit:

1.Faites en sorte que la vue parent (vue du contenu de votre activité) soit cliquable et se concentre en ajoutant les attributs suivants

    Android:clickable="true" 
    Android:focusableInTouchMode="true" 

2.Implémenter une méthode hideKeyboard ()

    public void hideKeyboard(View view) {
        InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

3. Enfin, définissez onFocusChangeListener de votre edittext.

    edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                hideKeyboard(v);
            }
        }
    });
0
Rajul Goel

défini dans un bouton ou une vue: this.getCurrentFocus (). clearFocus (); Par exemple:

@Override
public boolean onMenuOpened(int featureId, Menu menu) {
    InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    this.getCurrentFocus().clearFocus();
    return super.onMenuOpened(featureId, menu);
}
0
nobjta_9x_tq

Le code suivant fonctionne parfaitement pour moi et je l'utilise régulièrement pour fermer le SoftKeyboard onTouch n'importe où en dehors de EditText.

public void hideSoftKeyboard()
{
        //Hides the SoftKeyboard
        InputMethodManager inputMethodManager = (InputMethodManager)  getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}

public void setupUI(View view) 
{
        String s = "inside";
        //Set up touch listener for non-text box views to hide keyboard.
        if (!(view instanceof EditText)) {

            view.setOnTouchListener(new View.OnTouchListener() {

                public boolean onTouch(View v, MotionEvent event) {
                    hideSoftKeyboard();
                    return false;
                }

            });        
        }


    //If a layout container, iterate over children and seed recursion.
        if (view instanceof ViewGroup) {

            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {

                View innerView = ((ViewGroup) view).getChildAt(i);

                setupUI(innerView);
            }
        }    
}

Il vous suffit donc d'appeler la fonction setupUI() une fois dans votre méthode onCreate() et voila, votre hidingSoftKeyboard est configuré!

Pour Perdre le focus complet de EditText, faites simplement editText.clearFocus() dans votre fonction hideSoftKeyboard ().

0
Kaushik NP