2 pièce(s) jointe(s)
ListView avec checkbox et adapter
Bonjour, je commence à développé sous Android et je suis bloqué sur un cas tordu.
Contexte : j'ai une ListActivity avec un champ EditText, un Button, et une ListView. La liste contient deux champs texte et une checkbox. J'ai créé une classe basée sur un SimpleCursorAdapter pour gérer le contenu de la liste, et aussi pour intercepter le changement d'état du checkbox.
Problème : lorsque je clique sur le checkbox (dans la liste) je met à jour la base de données (pour mémoriser le statut de l'enregistrement). Et je souhaite ensuite mettre à jour le curseur de l'adapter dans le but d'afficher ma liste convenablement (lors de l'affichage du clavier virtuel par exemple). Et le problème se produit ici... ça ne marche pas comme je voudrais.
Détail : en appelant notifyDataSetChanged il régénère un évènement onCheckedChanged. C'est comme si j'avais cliqué de nouveau sur le checkbox. En plus il n'affiche plus correctement les lignes (avec remplacement d'un élément par un autre).
J'ai placé deux screens dans les pièces jointes. Le premier correspond à mon écran au démarrage (affichage des produits A,B,C,D), le deuxième correspond à mon écran après un clic sur la checkbox du "Produit B". La liste affiche alors les produits A,B,A,D...
Vous trouverez si dessous le code qui me permet d'initialiser ma liste :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
public void initListView() {
Cursor cursor = null;
try {
setListAdapter(null);
cursor = dbh.fetchAllObject(idcaddee,"name asc");
if(cursor != null) {
if(cursor.moveToFirst()) {
startManagingCursor(cursor);
ObjectListCursorAdapter adpater = new ObjectListCursorAdapter(this, R.layout.detail_listview, cursor,
new String[] {"name"}, new int[] {R.id.name});
setListAdapter(adpater);
}
}
}
catch(Exception e){
e.printStackTrace();
}
} |
Et ici le code de ma classe adapter (avec interception événement checkbox):
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| public class ObjectListCursorAdapter extends SimpleCursorAdapter implements OnCheckedChangeListener {
private DataBaseHelper dbh;
private int layout;
public ObjectListCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout = layout;
this.dbh = new DataBaseHelper(context);
this.dbh.open();
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
ViewHolder holder = new ViewHolder(v);
v.setTag(holder);
bindView(v, context, cursor);
holder.getCbStatus().setOnCheckedChangeListener(this);
return v;
}
@Override
public void bindView(View v, Context context, Cursor c) {
ViewHolder holder = (ViewHolder)v.getTag();
TextView tv = null;
CheckBox cb = null;
if((cb = holder.getCbStatus()) != null) {
cb.setChecked(c.getInt(c.getColumnIndex("status")) == 1 ?
true : false);
cb.setTag(c.getLong(c.getColumnIndex("_id")));
}
if((tv = holder.getName()) != null) {
tv.setText(c.getString(c.getColumnIndex("name")));
}
if((tv = holder.getComment()) != null) {
tv.setText(
c.getString(c.getColumnIndex("quantity"))+" "+
c.getString(c.getColumnIndex("unity")));
}
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
try{
if(buttonView.isPressed() == true) {
ContentValues values = new ContentValues();
values.put("status",isChecked == true ? 1:0);
long rowid = (Long) buttonView.getTag();
dbh.updateObject(rowid,values);
this.notifyDataSetChanged();
}
}
catch(Exception e){
e.printStackTrace();
}
}
} |
CustomAdapter : déphasage entre view et position
J'ai créé une classe basé sur SimpleCursorAdapter. Sur l’évènement onCheckedChanged, je met à jour ma BDD et j'exécute la commande suivante : notifyDataSetChanged.
Je constate que ma classe parcourt les vues à l'envers (ordre inverse de l'ordre de création) mais avec les positions d'origine. Je m'explique via un schéma :
Au lancement, création des vues :
Vue A : position 0
Vue B : position 1
Vue C : position 2
Après un clic sur un checkbox :
Vue C : position 0
Vue B : position 1
Vue A : position 2
Comment expliquer cela ? Que faut il faire pour ne pas avoir de déphasage.
PS : post relatif : http://www.developpez.net/forums/d10...ckbox-adapter/