Sapere quando una vista in un ListView è scomparsa sullo schermo?

Ho scoperto questo ma non riesco a trovare una risposta, quindi qui va …

Ho un ListView che mostra un text e un'image. L'adattatore sottostante ricicla le visualizzazioni per i motivi di performance (secondo l'approccio consigliato) e caricherò le immagini utilizzando un'AsynchTask secondo la raccomandazione trovata nella pagina bitmap del sito Android Developers .

  • L'elenco Completo Cocos2d-x Tutorial & Guida
  • NullPointerException su EditText situato in Dialog
  • Dove posso mettere un disegno disegnabile nelle mie cartelle Android?
  • trascinare il text in goccia a goccia in android
  • Cambia directory build gradle in studio android?
  • android - utilizzare la camera senza vista di superficie o textureview
  • Tutto funziona perfettamente e senza problemi, ma ho un problema. Quando la vista nella scheda viene riciclata, ha ancora un riferimento all'image vecchia (ImageView). Se l'utente scorre lentamente, l'AsynchTask ha abbastanza tempo per caricare la nuova image e visualizzarla, pertanto non è visibile riaggiungere la nuova image all'utente.

    Tuttavia, se l'utente scorre molto velocemente, il ritardo nel caricamento dell'image significa che vedono l'image vecchia (caricata quando la vista è stata utilizzata da un altro elemento) prima di essere sostituita dalla nuova image.

    Quindi, la mia domanda è, come posso rilevare quando una vista non è più visibile sullo schermo, quindi posso quindi rimuovere l'image? Ciò significa che l'utente vede un elemento di visualizzazione di elenco vuoto che verrà eventualmente caricato con l'image appropriata, che potrebbe sembrare migliore.

    Molte grazie in anticipo. Ecco il codice dell'adattatore di visualizzazione delle liste.

    @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; ListViewHolder viewHolder; // if this is not a recycled view then create a new view for the data... if (view == null) { view = this.inflater.inflate(R.layout.target_list_view_layout, null, true); viewHolder = new ListViewHolder(); viewHolder.manufacturer = (TextView) view.findViewById(R.id.manufacturer); viewHolder.targetName = (TextView) view.findViewById(R.id.targetName); viewHolder.targetThumbnail = (ImageView) view.findViewById(R.id.targetThumbnail); view.setTag(viewHolder); } else { viewHolder = (ListViewHolder) convertView.getTag(); } TargetDescriptor targetDescriptor = this.selectedTargets.get(position); viewHolder.manufacturer.setText(targetDescriptor.manufacturer); viewHolder.targetName.setText(targetDescriptor.targetName); // At this point I pass the image view reference to my background task to load the image LoadImageViewAsynchTask loadImageTask = new LoadImageViewAsynchTask(viewHolder.targetThumbnail, targetDescriptor); loadImageTask.execute(new Integer[] { 64, 64 }); return view; } 

    EDIT: coloro che utilizzano l'applicazione Android di eBay possono vedere l'effetto che sto cercando se questo aiuti.

  • Android: come impostare il colore di un text di Toast
  • Ha qualsiasi API di Android per fornire data-ora come input dell'utente (startActivityForResult)?
  • Redirect alle impostazioni di localizzazione usando cordova in android
  • come leggere la cache di L2 hit / miss rate in Android (ARM)?
  • Come fare admob mostra sempre un annuncio su android?
  • Crea notifiche personalizzate
  • 4 Solutions collect form web for “Sapere quando una vista in un ListView è scomparsa sullo schermo?”

    In realtà c'è un modo più semplice per farlo, puoi usare un ascoltatore:

     mListView.setRecyclerListener(new AbsListView.RecyclerListener() { @Override public void onMovedToScrapHeap(View view) { } }); 

    Non riesco a credere quanto sono stato stupido, è una soluzione molto facile da risolvere!

    Fondamentalmente nella mia scheda se la vista viene riciclata, ho semplicemente bisogno di annullare la bitmap di ImageView prima che la visualizzazione venga riutilizzata. Ciò significa che l'image nella voce di visualizzazione di elenco è vuota prima che l'image successiva venga caricata. Non ho più il problema della vecchia image mentre la nuova image viene caricata in background.

    Ho anche apportto una modifica nell'adattatore che cancella qualsiasi AsynchTask corrente legata alla vista che potrebbe ancora caricare un'image precedente che non è più necessaria. Questo è stato molto diffuso quando scorrimento molto veloce attraverso la vista di elenco, con spesso due o più carichi di immagini di backup, in modo che l'image cambierebbe diverse volte prima di stabilire l'image corretta.

    Ecco il nuovo codice, con le modifiche commentate in modo da poter vedere cosa sta succedendo:

     @Override public View getView(int position, View convertView, ViewGroup parent) { ListViewHolder viewHolder; // if this is not a recycled view then create a new view for the data... if (convertView == null) { convertView = this.inflater.inflate(R.layout.target_list_view_layout, null, true); viewHolder = new ListViewHolder(); viewHolder.manufacturer = (TextView) convertView.findViewById(R.id.manufacturer); viewHolder.targetName = (TextView) convertView.findViewById(R.id.targetName); viewHolder.targetThumbnail = (ImageView) convertView.findViewById(R.id.targetThumbnail); convertView.setTag(viewHolder); } else { viewHolder = (ListViewHolder) convertView.getTag(); // Cancel the previous attempt to load an image as this is going to be superceded by the next image viewHolder.loadImageViewAsynchTask.cancel(true); // Clear down the old image so when this view is displayed, the user does not see the old image before the // new image has a chance to load in the background viewHolder.targetThumbnail.setImageBitmap(null); } TargetDescriptor targetDescriptor = this.selectedTargets.get(position); viewHolder.manufacturer.setText(targetDescriptor.manufacturer); viewHolder.targetName.setText(targetDescriptor.targetName); LoadImageViewAsynchTask loadImageViewAsynchTask = new LoadImageViewAsynchTask(viewHolder.targetThumbnail); loadImageViewAsynchTask.setTargetDescriptor(targetDescriptor); loadImageViewAsynchTask.execute(new Integer[] { 64, 64 }); // Keep a reference to the task so we can cancel it if the view is recycled next time round to prevent // un-neccessary image loads that are out of date viewHolder.loadImageViewAsynchTask = loadImageViewAsynchTask; return convertView; } 

    Se si utilizza un LruCache per le bitmap e each visualizzazione nell'elenco di elenco mantengono la chiave dell'elemento LruCache, è ansible controllarlo meglio. Quindi, in getView, prova prima di get la bitmap dal LruCache e solo scaricarla di nuovo se non lo è.

    Inoltre, è ansible impostare un setOnScrollListener () sul ListView e utilizzare il relativo parametro visibleItemCount per regolare la dimensione del LruCache la prima volta che scorre l'utente.

    se si utilizza il metodo getView per le immagini di visualizzazione in modo da poter controllare convertView. se fosse nullo allora si può scoprire che è riciclato o non è inizializzato prima. semplicemente come questo:

      @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder viewholder; if (convertView == null) { viewholder = new ViewHolder(); inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.item_row, parent, false); viewholder.tvID = (TextView) convertView.findViewById(R.id.tvID); viewholder.tvName = (TextView) convertView.findViewById(R.id.tvName); viewholder.tvFamily = (TextView) convertView.findViewById(R.id.tvFamily); viewholder.ivMain = (ImageView) convertView.findViewById(R.id.ivMain); } else { viewholder = (ViewHolder) convertView.getTag(); } viewholder.tvID.setText(IDs[position]); viewholder.tvName.setText(Names[position]); viewholder.tvFamily.setText(Familys[position]); viewholder.ivMain.setImageResource(Images[position]); convertView.setTag(viewholder); return convertView; } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.