IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

Perte de donnée quant je scroll sur une ListView


Sujet :

Composants graphiques Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2002
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2002
    Messages : 203
    Par défaut Perte de donnée quant je scroll sur une ListView
    Bonjour,
    Je continue mon projet, et vient de découvrir un problème que j'ai du mal a comprendre.
    J'ai une listview qui charge plein d'Edittext, suffisamment plein pour que je soit obligé de scroller pour remplir les éléments du dessous.
    Par contre, quant je scroll a nouveau en haut, les valeurs précédemment remplies du haut ont disparues.
    Si je re-scroll vers le bas, les éléments cachés du bas eux aussi ont disparu?

    De plus, quant j'essaye d'identifier les objets avec getChild, par exemple, sur 11 EditText existant, il n'en trouve que 8, les autres sont en NullPointException

    Avez vous une idée ?

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    C'est le principe même d'une ListView... le recyclage des views pour éviter d'avoir 10Mo de views en mémoire.

    Si c'est gérer des checkbox, les ListView ont de base un système de multi-selection le permettant.
    Si c'est pour gérer des TextEdit par contre, il faut impérativement stocker leur valeur dès leur mise à jour. Si une validation de l'utilisateur est nécessaire après (c'est non recommandé dans les "us" d'Android, mais sait-on jamais), il faut donc les stocker dans une table temporaire.

  3. #3
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2002
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2002
    Messages : 203
    Par défaut
    Je comprend le principe,
    Apres quelques recherches sur le net, ils parlaient d'utiliser un ViewHolder, mais après test sur mon code, ca change rien...

    Si je mémorise les valeurs a chaque fois quelle sont saisies, bon, ok, je vois comment faire, mais comment les ré-afficher quant on scroll a nouveau ?

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Un exemple (parmi d'autres je pense):

    Disons que les objets de départ sont de type "MyObject", je vais partir d'un ArrayAdapter, mais le principe est le même pour tout autre type....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    class MyAdapter extends ArrayAdapter<MyObject>
    {
         private SparseArray<String>  editedValues;
     
         public MyAdapter(Context ctxt, MyObject[] objs)
         {
              super(ctxt,R.layout.my_edit_layout.xml,objs);
              this.editedValues = new SparseArray<String>();
         }
     
         @Override
         public View getView(int position, View convert, ViewGroup parent)
         {
               View ret = super.getView(position,convert,parent);
               // on récupère le "EditText"
               EditText edt = (EditText) ret.findViewById(R.id.my_text_edit);
     
               // il faut lui mettre les bonnes données !
               String edited = this.editedValues.get(position);
               if (edited == null) {
                   MyObject obj = getItem(position);
                   // on lui colle le texte par défaut de l'objet
                   edt.setText(obj.getText());
               } else {
                   // la valeur a été modifiée, on lui colle la valeur stockée !
                   edt.setText(edited);
               }
     
               // on lui colle un text-watcher qu'on va conserver sous le coude (Tag) pour pouvoir le supprimer si la vue est recyclée.
               TextWatcher watcher = (TextWatcher) edt.getTag();
               if (watcher != null) edt.removeTextChangedListener(watcher);
               watcher = new ListTextWatcher(position);
               edt.addTextChangedListener(watcher);
               edt.setTag(watcher);
     
               return ret;
         }
     
         // Une inner class pour le watcher:
         private class ListTextWatcher implements TextWatcher {
              int position;
     
              public TextWatcher(int p) { this.position = p; }
     
              public void    afterTextChanged(Editable s)  {
              {
                  MyAdapter.this.editedValues.put(this.position,s.toString());
              }
     
              public void    beforeTextChanged(CharSequence s, int start, int count, int after) {}
              public void    onTextChanged(CharSequence s, int start, int before, int count) {}
         }
     
    }
    et voilà....

    Le SparseArray contiendra toutes les modifications de texte effectuées...

  5. #5
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2002
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2002
    Messages : 203
    Par défaut
    ok, merci je vais essayer ca dans la journée.

    Par contre, a quoi sert le ViewHolder que je vois partout ?

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Le "ViewHolder" est une astuce permettant de faire pointer directement une "View" vers des fils préalablement trouvés avec findViewById.

    En cas d'arborescence complexe ou profonde, le findViewById peut être un poil long (genre 1ms hein !), et du coup, on le faisait une fois, on stockait le résultat dans le "ViewHolder" (qu'on collait en "tag" justement), et on n'avait plus à le refaire en cas de recyclage de la view.

    Déjà à l'époque je considérais que pour un layout avec 2 views, le findViewById était suffisamment court pour ne pas avoir recourt à ce "ViewHolder".
    Maintenant, vu l'évolution des téléphones c'est encore plus vrai.

    Toutefois, si vous désirez passer par un "ViewHolder", il suffit de lui rajouter le TextWatcher, et de le modifier à la volée (au lieu de conserver le TextWatcher directement dans le tag, il le sera dans le ViewHolder).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    ViewHolder holder = ret.getTag();
    if (holder == null) {
        holder = new ViewHolder();
        holder.textEdit = (TextEdit) ret.findViewById(R.id.my_text_edit);
        ret.setTag(holder);
    } else 
        holder.textEdit.removeTextChangeListener(holder.watcher);
     
    // on setup la value...
    holder.textEdit.setText(....);
     
    // on setup le watcher...
    holder.watcher = new ListTextWatcher(position);
    holder.textEdit.addTextChangeListener(holder.watcher);

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de Scroll sur Une TStringGrid en mode saisie
    Par Delphi-ne dans le forum Delphi
    Réponses: 5
    Dernier message: 23/10/2006, 09h50
  2. Afficher les données d'un champ sur une ligne
    Par white-angel dans le forum Access
    Réponses: 6
    Dernier message: 30/08/2006, 11h09
  3. Scrolling sur une ListBox
    Par dede92 dans le forum Windows
    Réponses: 2
    Dernier message: 02/06/2006, 18h56
  4. enregistrer les données d'un FORMULAIRE sur une TABLE
    Par godzinho dans le forum Access
    Réponses: 15
    Dernier message: 11/03/2006, 18h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo