2010-07-07 7 views
8

J'ai lu sur le problème de getView appelé plusieurs fois et toutes les réponses. Cependant, je ne trouve pas de solution à mon problème.Android Adaptateur multiple getView

J'ai une liste où les lignes ont deux états: lu ou non. Bien, je veux que les articles vus pour la première fois aient une couleur différente et quand je fais défiler la liste, ils changent leur couleur en "état de lecture". Pour ce faire, dans la méthode getView de mon adaptateur, je définis un champ isRead lorsque la ligne de cet élément est peinte. Mais le problème est le suivant: puisque la méthode getView est appelée plusieurs fois, le champ est marqué comme lu et lorsque la liste est affichée à l'écran, elle apparaît comme si elle avait déjà été lue.

Une idée pour résoudre ce problème?

Merci

Répondre

14

Je suppose que vous voulez dire le problème de getView demandant la même vue plusieurs fois.

ListView fait cela parce qu'il a besoin d'obtenir des mesures pour les vues pour différentes raisons (taille de la barre de défilement, mise en page, etc.)

Ce problème peut généralement être évité en ne pas utiliser la propriété « wrap_content » sur votre listview. A part cela, utiliser getView pour déterminer si une vue a été affichée est simplement une mauvaise idée. ListView a de nombreuses optimisations qui affectent l'ordre dans lequel getView est appelé pour chaque ligne, il n'y a donc aucun moyen de savoir ce qui se passera et votre application commencera à montrer un comportement étrange. Essayez d'éviter toute relation entre la vue et les données autres que le concept de vue en tant qu'affichage de ces données. Au lieu de cela, ayez un thread de travail ou un écouteur d'événement dans votre liste d'activités surveillez la liste des éléments de la liste qui ont été affichés à l'utilisateur, mettez à jour les données et appelez dataSetChanged sur votre adaptateur.

+0

"mettre à jour les données, et appelez dataSetChanged sur votre adaptateur" - fonctionne pour moi –

0

Pas comme vous le souhaitez. La raison pour laquelle getView() est appelée plusieurs fois est de permettre au système d'exploitation de mesurer les lignes afin qu'il sache comment les mettre en page. Vous devriez l'avoir marqué comme lu quand ils cliquent dessus ou vérifient une boîte ou quelque chose.

1

J'ai eu le même problème et je n'avais aucune référence à "wrap_content" dans les dispositions attirbute. Bien que ce soit un vieux fil de discussion, je n'ai pas pu trouver de solution à ce problème. Ainsi, je l'ai atténué en ajoutant une liste dans l'adaptateur qui contient les positions déjà dessinées, comme indiqué dans le code ci-dessous. Je pense que ce n'est pas le cas tout de suite, mais cela a fonctionné pour moi.

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 
    private List<Integer> usedPositions = new ArrayList<Integer>(); 

    public ImageAdapter(Context c, List<String> imageUrls) { 
     mContext = c; 
     ... 
    } 

    ... 

    // create a new ImageView for each item referenced by the Adapter 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { 
      imageView = new ImageView(mContext); 
      imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
      imageView.setPadding(8, 8, 8, 8); 
     } else { 
      imageView = (ImageView) convertView; 
     } 

     if (!usedPositions.contains(position)) { 
      // Your code to fill the imageView object content 
      usedPositions.add(position); // holds the used position 
     } 

     return imageView; 
    } 
} 
0

Voici une manière très simple d'éviter le double appel quand vous savez que rien en dessous de ce bloc de code ne déformera la disposition.

private static List<String> usedPositions = new ArrayList<String>(); 

...

@Override 
public View getView(int position, View rowView, ViewGroup parent) { 
    rowView = inflater.inflate(R.layout.download_listview_item, null); 

    Log.d(LOG_TAG, "--> Position: " + position); 

    if (!usedPositions.contains(String.valueOf(position))){ 
     usedPositions.add(String.valueOf(position)); 
     return rowView; 
    }else{ 
     usedPositions.remove(String.valueOf(position)); 
    } 

...

Questions connexes