web-dev-qa-db-fra.com

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

Je sais qu'il y a beaucoup de questions similaires ici, mais je n'ai pu faire fonctionner aucune des solutions fournies dans un exemple d'application simple.

Le problème se produit lorsque le softkeyboard s'affiche pour la première fois. Dès qu'il est affiché, ce n'est qu'en appuyant sur editText qu'il est de nouveau modifiable.

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é une fois que le clavier logiciel apparaît. Malheureusement, cela entraîne également la perte de focus de EditTexts. Il s'agit probablement de ListView lui-même gagnant le focus après le processus de redimensionnement. J'ai donc essayé la solution de contournement suivante:

 listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

Cela provoque toujours le premier EditText visible que le ListView contient pour gagner le focus, ce qui n'est pas souhaitable. Le deuxième EditText de la deuxième ligne devrait à la place gagner le focus lorsqu'il est pressé, ce qui ne se produit pas. De plus, si j'ai finalement réussi à concentrer un autre EditText autre que le premier affiché (par exemple en appuyant sur 'Suivant' sur le softkeyboard), le premier visible recevra le focus après que le clavier soit fermé et que le ListView soit redimensionné à sa pleine taille à nouveau.

J'ai essayé plusieurs autres choses comme intercepter les événements onFocusChange() pour le ListView, tout en sachant quel EditText a été pressé par son TouchListener. Demander à nouveau le focus pour cet certain EditText n'a pas non plus abouti.

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

63
Display name

Un hack classique pour des situations comme celle-ci consiste à 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 de production. Je ne serais pas non plus surpris si le bug de focus se manifestait différemment dans différentes versions Android versions ou roms.

Il existe également de nombreux autres problèmes avec l'incorporation d'un EditText dans un ListView qui ont des solutions qui ressemblent à un hack. Voir tous les autrepersonnes en difficulté.

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

like this.

Après avoir emprunté plusieurs fois des chemins similaires moi-même, j'ai surtout renoncé à essayer de remplacer tous les comportements ou bizarreries du clavier par défaut. Je recommanderais d'essayer de trouver une solution alternative dans votre application si possible.

Avez-vous envisagé que les lignes ListView soient simplement un style TextView, puis affichez un Dialog avec un EditText lorsque vous cliquez sur une ligne, en mettant à jour TextView comme nécessaire?

42
Kyle Ivey

J'avais des problèmes avec le focus "Vol" de l'ActionBar lorsque j'ai appuyé sur un EditText situé dans une ligne 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

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

Android:descendantFocusability="beforeDescendants"

et l'a ajouté à mon activité:

Android:windowSoftInputMode="adjustPan"
39
gonzobrains

Modifiez votre XML manifeste pour ajouter windowSoftInputMode dans votre activité:

<activity
    Android:name=".YourActivity"
    Android:windowSoftInputMode="adjustPan">
</activity>
19
nlmm01

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

Passez à 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.

8
ShahrozKhan91

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

Enfin, le problème dans mon cas était que le recyclerView avait wrap_content comme valeur pour la hauteur sur mon XML par accident; l'a changé en match_parent et a commencé à fonctionner comme prévu, aucune valeur focusable définie et à l'aide de Android:windowSoftInputMode="adjustResize"

2
Omer

Lorsque la liste est suffisamment longue pour couvrir le clavier virtuel, le EditText dans Listview perd le focus lorsque vous appuyez sur Android 4.x.

Une solution consiste à envelopper le Listview dans une disposition linéaire avec une hauteur de la moitié de l'écran.

Chaque fois que le Listview ne couvre pas le clavier logiciel, tout va bien.

1
Kai Wang

Utilisez Recycler View, cela résout plusieurs problèmes de liste et de grille. Vous pouvez même travailler avec des vues de grille décalées. Yo pourrait facilement commencer à travailler avec cela http://Android-er.blogspot.com.co/2015/07/staggeredgridlayoutmanager-google-app.html

1
user1176776

Dans mon cas, j'ai ajouté une valeur locale actuellement FocusFrow dans mon adaptateur. Dans la méthode getView (), j'ai ajouté ce code à chaque editText:

   if (currentlyFocusedRow == position) {
        editText.requestFocus();
   }

        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    if (currentlyFocusedRow == -1) {
                        currentlyFocusedRow = position;
                    }
                } else {
                    currentlyFocusedRow = -1;
                }
            }
        });
0
Malder

avait le même problème. Recherche de toutes ces solutions avec inputMode, focusability et al. Meilleure solution, migrez vers la vue recycleur.

0
Aman Agarwal