405 votes

Comment cacher le clavier programmable sur android après avoir cliqué sur EditText extérieur ?

Ok tout le monde sait que pour masquer un clavier, vous devez mettre en œuvre:

InputMethodManager imm = (InputMethodManager) getSystemService(
    INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

Mais le gros problème ici est de savoir comment masquer le clavier lorsque l'utilisateur touche ou sélectionne tout autre endroit qui n'est pas une zone de texte ou la softKeyboard?

J'ai essayé d'utiliser le onTouchEvent sur mon Activité parent mais qui ne fonctionne que si l'utilisateur touche en dehors de tout autre point de vue, et il n'est pas le scrollview.

J'ai essayé de mettre en œuvre un contact, cliquez sur, l'accent auditeur sans aucun succès.

J'ai même essayé de mettre en place mes propres scrollview pour intercepter les événements tactiles, mais je ne peux obtenir les coordonnées de l'événement et non pas le point de vue cliqué.

Est-il un moyen standard pour ce faire?? dans iPhone, il était vraiment facile.

604voto

Voici ce que j'ai fait pour mon application, et il fonctionne comme, attendez, parfait!

D'abord voici le code qui cache simplement le clavier:

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

Vous pouvez mettre cela en place dans une classe utilitaire, ou si vous sont à définir au sein d'une activité, d'éviter l'activité paramètre, ou appelez - hideSoftKeyboard(this).

La partie la plus délicate est de savoir quand appeler. Vous pouvez écrire une méthode qui parcourt chaque View de votre activité, et de vérifier si c'est un instanceof EditText si elle n'est pas enregistrer un setOnTouchListener de cette composante et tout va tomber en place. Dans le cas où vous vous demandez comment faire, il est en fait assez simple. Voici ce que vous faites, vous écrivez une méthode récursive comme suit, en fait, vous pouvez l'utiliser pour faire quelque chose, comme le programme d'installation de polices de caractères personnalisées etc... Voici la méthode

public void setupUI(View view) {

    //Set up touch listener for non-text box views to hide keyboard.
    if(!(view instanceof EditText)) {

        view.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(MyActivity.this);
                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);
        }
    }
}

C'est tout, il suffit d'appeler cette méthode après l' setContentView dans votre activité. Dans le cas où vous vous demandez qu'est-ce paramètre vous voulez passer, c'est l' id du conteneur parent. Attribuer un id de votre conteneur parent comme

<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>

et appelez - setupUI(findViewById(R.id.parent)), c'est tout.

Si vous souhaitez utiliser efficacement, vous pouvez créer un Activity et de mettre cette méthode en, et de prendre toutes les autres activités dans votre application d'étendre cette activité et appeler ses setupUI() dans la onCreate() méthode.

Espérons que cela aide.

Si vous utilisez plus de 1 activité-définir l'id du parent de mise en page comme <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>

Puis étendre une classe à partir d' Activity et de définir setupUI(findViewById(R.id.main_parent)) à l'Intérieur de ses OnResume() et d'étendre cette classe à la place de l'Activité `in your program

319voto

vida Points 420

Vous pouvez atteindre cet objectif en faisant les étapes suivantes:

  1. Rendre la vue parent(l'affichage du contenu de votre activité) cliquables et peut recevoir le focus en ajoutant les attributs suivants

        android:clickable="true" 
        android:focusableInTouchMode="true" 
    
  2. 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(), 0);
        }
    
  3. Enfin, définissez la onFocusChangeListener de votre edittext.

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

Comme le souligne l'un des commentaires ci-dessous, cela pourrait ne pas fonctionner si la vue parent est un ScrollView. Dans de tels cas, la cliquables et focusableInTouchMode peut être ajouté sur la vue directement en vertu de la ScrollView.

64voto

roepit Points 103

J’ai trouvé la réponse acceptée un peu compliqué.

Voici ma solution. Ajouter un onTouchListener à votre disposition principale (ie. findViewById(R.id.mainLayout).setOnTouchListener(this)) et mettez le code suivant dans la méthode onTouch.

De cette façon, que vous n’avez pas à parcourir toutes les vues.

43voto

Saurabh Pareek Points 2954

Salut j’ai eu une solution plus à cacher le clavier par :

Ici, passez HIDE_IMPLICIT_ONLY à la position de showFlag et de 0 à la position de hiddenFlag. Elle fermera avec force clavier programmable.

16voto

htafoya Points 3207

Bien que j'ai réussi à résoudre un peu le problème, j'ai changé le dispatchTouchEvent sur mon activité, je suis en utilisant les éléments suivants pour masquer le clavier.

 /**
 * Called to process touch screen events. 
 */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

    switch (ev.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchDownTime = SystemClock.elapsedRealtime();
            break;

        case MotionEvent.ACTION_UP:
            //to avoid drag events
            if (SystemClock.elapsedRealtime() - touchDownTime <= 150){  

                EditText[] textFields = this.getFields();
                if(textFields != null && textFields.length > 0){

                    boolean clickIsOutsideEditTexts = true;

                    for(EditText field : textFields){
                        if(isPointInsideView(ev.getRawX(), ev.getRawY(), field)){
                            clickIsOutsideEditTexts = false;
                            break;
                        }
                    }

                    if(clickIsOutsideEditTexts){
                        this.hideSoftKeyboard();
                    }               
                } else {
                    this.hideSoftKeyboard();
                }
            }
            break;
    }

    return super.dispatchTouchEvent(ev);
}

EDIT: Le getFields() la méthode est juste une méthode qui retourne un tableau avec les objets textfield dans la vue. Pour éviter la création de ce tableau sur chaque touche, j'ai créé un tableau statique appelé sFields, qui est retourné à la getFields() la méthode. Ce tableau est initialisé sur le onStart() méthodes telles que:

sFields = new EditText[] {mUserField, mPasswordField};


Il n'est pas parfait, L'événement glisser le temps est uniquement basée sur l'heuristique si parfois il ne marche pas cacher lors de l'exécution de longues clics, et j'ai aussi fini par créer une méthode pour obtenir tous les editTexts par la vue; d'autre du clavier permettrait de masquer et d'afficher en cliquant sur d'autres EditText.

Encore, plus propre et plus courte, les solutions sont les bienvenues

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