135 votes

EditText, effacer le focus en touchant l'extérieur

Ma mise en page contient ListView , SurfaceView y EditText . Lorsque je clique sur l'icône EditText il reçoit le focus et le clavier à l'écran s'affiche. Lorsque je clique quelque part en dehors de la fenêtre EditText Il est toujours au centre de l'attention (il ne devrait pas l'être). Je pense que je pourrais configurer OnTouchListener sur les autres vues dans la mise en page et effacer manuellement les EditText L'accent est mis sur le Mais cela semble trop artificiel...

J'ai également la même situation dans l'autre présentation - une vue en liste avec différents types d'éléments, dont certains ont des caractéristiques EditText à l'intérieur. Ils agissent comme je l'ai écrit ci-dessus.

Il s'agit de faire EditText se déconcentrent lorsque l'utilisateur touche quelque chose en dehors de l'écran.

J'ai vu des questions similaires ici, mais je n'ai pas trouvé de solution...

3voto

Webserveis Points 1102

En Kotlin

hidekeyboard() est une extension Kotlin

fun Activity.hideKeyboard() {
    hideKeyboard(currentFocus ?: View(this))
}

Dans l'activité, ajouter dispatchTouchEvent

override fun dispatchTouchEvent(event: MotionEvent): Boolean {
    if (event.action == MotionEvent.ACTION_DOWN) {
        val v: View? = currentFocus
        if (v is EditText) {
            val outRect = Rect()
            v.getGlobalVisibleRect(outRect)
            if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                v.clearFocus()
                hideKeyboard()
            }
        }
    }
    return super.dispatchTouchEvent(event)
}

Ajouter ces propriétés dans le parent le plus élevé

android:focusableInTouchMode="true"
android:focusable="true"

2voto

Dhruvam Gupta Points 464

Il suffit de définir deux propriétés du parent de ce EditText comme :

android:clickable="true"
android:focusableInTouchMode="true"

Ainsi, lorsque l'utilisateur touchera l'extérieur de EditText le focus sera supprimé car le focus sera transféré à la vue parentale.

1voto

forumercio Points 122

Pour perdre le focus lorsque l'autre vue est touchée, les deux vues doivent être définies comme view.focusableInTouchMode(true).

Mais il semble que l'utilisation des focus en mode tactile ne soit pas recommandée. Jetez un coup d'œil ici : http://Android-developers.blogspot.com/2008/12/touch-mode.html

0voto

Alex Tran Points 739

La meilleure façon est d'utiliser la méthode par défaut [clearFocus()](http://developer.android.com/reference/android/view/View.html#clearFocus())

Vous savez comment résoudre les codes en onTouchListener n'est-ce pas ?

Il suffit d'appeler EditText.clearFocus() . Il s'agit d'une mise au point claire en last EditText .

0voto

Sabre Points 1169

Comme @pcans l'a suggéré, vous pouvez le faire en surchargeant dispatchTouchEvent(MotionEvent event) dans votre activité.

Nous obtenons ici les coordonnées du toucher et les comparons aux limites de la vue. Si le toucher est effectué en dehors d'une vue, il faut faire quelque chose.

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View yourView = (View) findViewById(R.id.view_id);
        if (yourView != null && yourView.getVisibility() == View.VISIBLE) {
            // touch coordinates
            int touchX = (int) event.getX();
            int touchY = (int) event.getY();
            // get your view coordinates
            final int[] viewLocation = new int[2];
            yourView.getLocationOnScreen(viewLocation);

            // The left coordinate of the view
            int viewX1 = viewLocation[0];
            // The right coordinate of the view
            int viewX2 = viewLocation[0] + yourView.getWidth();
            // The top coordinate of the view
            int viewY1 = viewLocation[1];
            // The bottom coordinate of the view
            int viewY2 = viewLocation[1] + yourView.getHeight();

            if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) {

                Do what you want...

                // If you don't want allow touch outside (for example, only hide keyboard or dismiss popup) 
                return false;
            }
        }
    }
    return super.dispatchTouchEvent(event);
}

Il n'est pas non plus nécessaire de vérifier l'existence et la visibilité des vues si la disposition de votre activité ne change pas au cours de l'exécution (par exemple, vous n'ajoutez pas de fragments ou ne remplacez/supprimez pas de vues de la disposition). Mais si vous voulez fermer (ou faire quelque chose de similaire) le menu contextuel personnalisé (comme dans le Google Play Store lorsque vous utilisez le menu de débordement de l'élément), il est nécessaire de vérifier l'existence de la vue. Sinon, vous obtiendrez un NullPointerException .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X