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é.
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:
.
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?
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"
Modifiez votre XML manifeste pour ajouter windowSoftInputMode dans votre activité:
<activity
Android:name=".YourActivity"
Android:windowSoftInputMode="adjustPan">
</activity>
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.
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"
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.
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
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;
}
}
});
avait le même problème. Recherche de toutes ces solutions avec inputMode, focusability et al. Meilleure solution, migrez vers la vue recycleur.