Listview avec adaptateur personnalisé contenant des Cases à cocher
J'ai une ListView qui utilise une coutume adaptateur comme indiqué:
private class CBAdapter extends BaseAdapter implements OnCheckedChangeListener{
Context context;
public String[] englishNames;
LayoutInflater inflater;
CheckBox[] checkBoxArray;
LinearLayout[] viewArray;
private boolean[] checked;
public CBAdapter(Context con, String[] engNames){
context=con;
englishNames=engNames;
inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
checked= new boolean[englishNames.length];
for(int i=0; i<checked.length; i++){
checked[i]=false;
//Toast.makeText(con, checked.toString(),Toast.LENGTH_SHORT).show();
}
checkBoxArray = new CheckBox[checked.length];
viewArray = new LinearLayout[checked.length];
}
public int getCount() {
return englishNames.length;
}
public Object getItem(int position) {
//TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
//TODO Auto-generated method stub
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
if(viewArray[position] == null){
viewArray[position]=(LinearLayout)inflater.inflate(R.layout.record_view_start,null);
TextView tv=(TextView)viewArray[position].findViewById(R.id.engName);
tv.setText(englishNames[position]);
checkBoxArray[position]=(CheckBox)viewArray[position].findViewById(R.id.checkBox1);
}
checkBoxArray[position].setChecked(checked[position]);
checkBoxArray[position].setOnCheckedChangeListener(this);
return viewArray[position];
}
public void checkAll(boolean areChecked){
for(int i=0; i<checked.length; i++){
checked[i]=areChecked;
if(checkBoxArray[i] != null)
checkBoxArray[i].setChecked(areChecked);
}
notifyDataSetChanged();
}
public void onCheckedChanged(CompoundButton cb, boolean isChecked) {
for(int i=0; i<checked.length; i++){
if(cb == checkBoxArray[i])
checked[i]=isChecked;
}
}
public boolean itemIsChecked(int i){
return checked[i];
}
}
Les mises en page sont assez simples, donc je ne vais pas les publier, à moins que quelqu'un pense qu'ils sont pertinents.
Le problème est que certaines Cases ne sont pas de répondre. Il semble être ceux qui sont visibles lors de la mise en page est affichée pour la première fois. Tout ce que vous avez à faire défiler vers le bas pour fonctionner comme prévu.
Tous les pointeurs apprécié.
OriginalL'auteur s1ni5t3r | 2012-09-28
Vous devez vous connecter pour publier un commentaire.
Votre code à partir de la réponse fonctionne, mais est inefficace(on peut effectivement voir cela, il suffit de faire défiler la
ListView
et vérifier laLogcat
pour voir le garbage collector de faire, c'est le travail). Une amélioration de lagetView
méthode qui permettra de recycler les points de vue est celui ci-dessous:Au sujet de votre code à partir de votre question, j'ai d'abord pensé que c'était mauvais à cause de la façon dont vous configurez les lignes, mais je ne vois pas pourquoi la carte ont un comportement comme le détachement de la ligne vue depuis la liste. Aussi, j'ai même testé le code et il fonctionne très bien concernant
CheckBoxes
(mais avec de la mauvaise gestion de la mémoire). Peut-être que vous êtes en train de faire quelque chose d'autre qui fait que l'adaptateur ne fonctionne pas?Vous aurez envie d'utiliser le
getChildView()
méthode qui est appelée à chaque fois qu'une ligne enfant est nécessaire.qu'est-ce que mchecked dans ce cas et comment le déclarer?
C'est un booléen tableau qui est aussi grand que le nombre d'éléments dans la
ListView
. Il déclare dans le constructeur de la carte.merci monsieur il m'a beaucoup aidé. j'ai résolu mon problème
OriginalL'auteur Luksprog
Permettez-moi d'abord de dire que vous avez jeté l'un des principaux avantages de l'utilisation d'un adaptateur: Réutilisable points de vue. La tenue d'une dur de référence pour chaque
View
est titulaire d'un risque élevé de frapper la mémoire de plafond. Vous devriez être en réutilisantconvertView
quand elle est non-nulle, et la création de votre point de vue lorsqueconvertView
est null. Il existe de nombreux tutoriels qui vous montrent comment faire.Vues utilisées dans un adaptateur disposent généralement d'un
OnClickListener
attaché à eux par le parentView
de sorte que vous pouvez définir unOnItemClickListener
sur leListView
. Cette prévalent en cas de toucher les auditeurs sur les différents points de vue. Essayez de définirandroid:clickable="true"
sur leCheckBox
en XML.OriginalL'auteur Jason Robinson
Cela peut ne pas être la plus élégante ou solution efficace mais cela fonctionne pour ma situation. Pour une raison d'essayer de réutiliser les points de vue, soit à partir d'un tableau de points de vue ou à l'aide de convertView rend chaque chose aller wobbley et les Cases à cocher ne pas répondre.
La seule chose qui a fonctionné a été la création d'un nouveau point de Vue à chaque fois que getView() est appelée.
Trouver cette solution a également été entravé par le fait que j'ai été appeler un définies séparément onCheckedChangedListener, qui a ensuite identifié dont la Case par id, plutôt que d'avoir un nouveau port d'écoute pour chaque Case à cocher.
Encore je n'ai pas marqué ceci comme la réponse correcte comme je suis en espérant que d'autres peuvent avoir certains commentaires concernant la plutôt gourmande la reconstruction de la vue à chaque fois.
ListView
avec un adaptateur personnalisé qui utilise une ligne avec unCheckBox
, vous devriez examiner de plus près ces solutions. Votre code fonctionne, mais c'est très inefficace, à chaque fois que leListView
défile à l'écran, vous apprendrez à créer de nouvelles vues.Je suis totalement d'accord Luksprog mais après de nombreuses tentatives de ce, à l'aide de solutions de travail pour les autres, je ne peux pas trouver une solution qui fonctionne, d'autres que cela. Espérons que la collecte des ordures va suivre gaspillage de points de vue et de ne pas causer un problème de mémoire et de vieux téléphones ne sera pas ralenti trop. Dans mon application, dans la plupart des situations, la liste n'aura pas trop d'entrées afin de défilement doit être maintenu à un minimum.
La raison pour laquelle votre code fonctionne maintenant, c'est parce que vous gonflez la ligne à chaque fois et vous éviter les
OnCheckedChangeListener
gâcher laCheckBox
état. Vous ne devriez jamais ignorer vue de recyclage dans legetView
méthode. Ici est votre amélioration de lagetView
méthode qui devrait faire ce que vous voulez, mais permettra également de recycler les points de vue. gist.github.com/3917222Excellent. Qui fonctionne exactement comme prévu. Votre code a chuté de droite uniquement avec la " m " retiré de la "vérifié" array. (C'est mon premier projet en java et je n'étais pas au courant des conventions.) J'ai maintenant 2 faveurs à demander. 1. Pouvez-vous reposter cela comme une réponse afin que je puisse le définir comme acceptée et 2. Pouvez-vous expliquer exactement pourquoi cela fonctionne quand mon code dans le post original, n'est-ce pas. J'ai le sentiment que la réponse peut faire la lumière sur certains autres concepts que je suis aux prises avec.
OriginalL'auteur s1ni5t3r