65 votes

EditText dans Listview perd le focus lorsqu'il est appuyé sur Android 4.x

Je sais qu'il y a beaucoup de questions similaires ici mais je n'ai réussi à faire fonctionner aucune des solutions fournies dans une application de test simple.

Le problème survient lorsque le clavier virtuel est affiché pour la première fois. Dès qu'il est affiché, il est seulement possible de le rendre éditable en appuyant à nouveau sur editText.

J'ai essayé ce qui suit:

 android:windowSoftInputMode="adjustPan|adjustResize"

Cela ne résout aucun problème. Il semble que cette ligne soit obligatoire pour redimensionner l'activité après l'affichage du clavier virtuel. Malheureusement, cela entraîne également la perte du focus pour tout EditText. Cela est probablement dû au fait que le ListView lui-même gagne le focus après le redimensionnement. J'ai donc essayé l'astuce suivante:

 listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

Cela fait toujours en sorte que le premier EditText visible contenu dans le ListView gagne le focus, ce qui est indésirable. Le deuxième EditText dans la deuxième rangée devrait plutôt gagner le focus lorsqu'il est pressé, ce qui n'arrive pas. De plus, si j'arrive finalement à mettre le focus sur un autre EditText que le premier affiché (par exemple en appuyant sur 'Suivant' sur le clavier virtuel), le premier affiché recevra le focus après que le clavier soit caché et que le ListView soit redimensionné à sa taille normale.

J'ai essayé plusieurs autres choses comme intercepter les événements onFocusChange() pour le ListView, tout en sachant quel EditText a été pressé grâce à son TouchListener. Demander à ce certain EditText de reprendre le focus n'a pas non plus donné de résultats.

Utiliser un ScrollView au lieu d'un ListView comme suggéré par d'autres utilisateurs n'est pas une option pour le projet concerné.

0 votes

Salut, je suppose que ce qui se passe ici n'est pas que le EditText doit être pressé une fois de plus, pour être opérationnel, mais le fait que le clavier virtuel apparaît, car il est déclenché par un champ, qui est éditable et prend le focus au départ. Vous pouvez essayer ceci public void hideSoftKeyboard(View v) { Activity activity = (Activity) v.getContext(); InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); }.

0 votes

Cela empêchera le clavier virtuel d'apparaître au début et je suppose que l'EditText devrait simplement être pressé pour déclencher la modification dedans.

0 votes

@g00dy, le problème n'est pas que le clavier apparaît initialement mais entrer du texte ne fonctionne pas correctement.

44voto

Kyle Ivey Points 2120

Un hack classique pour des situations comme celle-ci est d'utiliser un gestionnaire et postDelayed(). Dans votre adaptateur:

private int lastFocussedPosition = -1;
private Handler handler = new Handler();

public View getView(final int position, View convertView, ViewGroup parent) {

    // ...

    edittext.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                handler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        if (lastFocussedPosition == -1 || lastFocussedPosition == position) {
                            lastFocussedPosition = position;
                            edittext.requestFocus();
                        }
                    }
                }, 200);

            } else {
                lastFocussedPosition = -1;
            }
        }
    });

    return convertView;
}

Cela fonctionne sur mon appareil, mais gardez ce code hors production. Je ne serais pas surpris non plus si le bogue de focus se manifeste différemment dans différentes versions d'Android ou roms.

Il y a aussi de nombreux autres problèmes avec l'intégration d'un EditText dans un ListView qui ont des solutions qui semblent être un hack. Voyez tous les autres personnes qui luttent.

Il est également très facile que quelque chose comme ceci se produise:

comme ça.

Après être passé par des chemins similaires de nombreuses fois, j'ai largement renoncé à essayer de remplacer les comportements ou bizarreries du clavier par défaut. Je vous recommande d'essayer de trouver une solution alternative dans votre application si possible.

Avez-vous envisagé de faire en sorte que les lignes de ListView soient simplement des TextView stylisés et d'afficher un Dialog avec un EditText lorsqu'une ligne est cliquée, en mettant à jour le TextView si nécessaire?

0 votes

Merci pour votre réponse, malheureusement nous ne pouvons pas changer la mise en page de notre application, donc nous devons utiliser des listViews à cet effet. Et nous utilisons déjà des dialogues en ce moment pour entrer du texte :) Beaucoup des réponses aux questions sont acceptées cependant, je me demande si cela a fonctionné pour ces personnes

2 votes

@GrafOrlov vous ne voulez probablement pas utiliser cette solution en production. Envisagez d'afficher un edittext dans une boîte de dialogue lorsque vous cliquez sur une ligne.

0 votes

@KyleIvey pouvez-vous aider à répondre à cette question s'il vous plaît? stackoverflow.com/questions/37358015/…

40voto

gonzobrains Points 2238

J'avais des problèmes avec l'ActionBar "volant" le focus lorsque je cliquais sur un EditText situé dans une ligne de ListView. Les solutions ci-dessus n'ont pas fonctionné, mais la solution suivante a fonctionné pour moi :

http://www.mysamplecode.com/2013/02/android-edittext-listview-loses-focus.html

Essentiellement, j'ai ajouté ceci à ma ListView :

android:descendantFocusability="beforeDescendants"

et ajouté ceci à mon activité :

android:windowSoftInputMode="adjustPan"

7 votes

Cela provoquera le blocage du clavier de l'EditText s'il se trouve en bas de la liste

19voto

nlmm01 Points 803

Modifiez votre manifest xml pour ajouter windowSoftInputMode dans votre activité:

8voto

ShahrozKhan91 Points 535

Je sais que c'est un fil de discussion très ancien, mais cette réponse pourrait être utile à quelqu'un, donc la voici :

Passer à RecyclerView et vous n'aurez pas à vous soucier de ces problèmes ennuyeux de ListView. Au lieu de créer une nouvelle vue, il recycle et réutilise les anciennes vues.

3voto

Omer Points 1255

J'avais le même problème avec recyclerView et j'essayais toutes les solutions suggérées.

Finalement, le problème dans mon cas était que le recyclerView avait wrap_content comme valeur pour la hauteur dans mon fichier XML par accident; je l'ai changé en match_parent et il a commencé à fonctionner comme prévu, aucune valeur focusable définie et en utilisant android:windowSoftInputMode="adjustResize"

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