2011-11-24 20 views
17

Ottengo voci duplicate in un ListView. Lo scorrimento indietro e in basso a volte cambia l'ordine dell'articolo. Ho cercato su Google e ho trovato molti thread che riportano questo bug, ma nessuno di questi mi ha aiutato a risolvere il problema.Voci duplicate in ListView

Ecco il mio codice:

Attività:

package com.github.progval.SeenDroid; 

import java.util.ArrayList; 
import java.util.List; 

import com.github.progval.SeenDroid.lib.Connection; 
import com.github.progval.SeenDroid.lib.Message; 
import com.github.progval.SeenDroid.lib.MessageFetcher; 
import com.github.progval.SeenDroid.lib.Query.ParserException; 

import android.app.Activity; 
import android.app.ListActivity; 
import android.content.SharedPreferences; 
import android.os.Bundle; 

public class ShowUserActivity extends ListActivity { 
    private Connection connection; 

    public ArrayList<Message> listMessages = new ArrayList<Message>(); 
    public MessageAdapter adapter; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.profile); 
     this.connection = new Connection(); 
     this.setTitle(R.string.homefeed_title); 


     this.listMessages = new MessageFetcher(this.connection).fetchUser(); 
     this.bindUi(); 
    } 

    private void bindUi() { 
     this.adapter = new MessageAdapter(this, this.listMessages); 
     this.setListAdapter(adapter); 

     // TODO Bind buttons 
    } 
} 

MessageAdapter:

package com.github.progval.SeenDroid; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.zip.Inflater; 

import com.github.progval.SeenDroid.lib.Message; 

import android.content.Context; 
import android.text.Layout; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.webkit.WebView; 
import android.widget.ArrayAdapter; 
import android.widget.BaseAdapter; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class MessageAdapter extends BaseAdapter { 
    private Context context; 
    private List<Message> items = new ArrayList<Message>(); 
    private int lastPosition = 0; 

    public MessageAdapter(Context context, List<Message> items) { 
     super(); 
     this.context = context; 
     this.items = items; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 

     if (null == convertView) { 
      LinearLayout view; 
      view = (LinearLayout) LinearLayout.inflate(this.context, R.layout.message, null); 
      Log.d("SeenDroid", String.format("Get view %d", position)); 
      TextView title = new TextView(view.getContext()); 
      title.setText(this.items.get(position).getTitle()); 
      view.addView(title); 
      return view; 
     } else { 
      return convertView; 
     } 
    } 


    @Override 
    public int getCount() { 
     return this.items.size(); 
    } 


    @Override 
    public Object getItem(int location) { 
     return this.items.get(location); 
    } 


    @Override 
    public long getItemId(int arg0) { 
     return arg0; 
    } 


} 

Tra l'altro, l'output è:

D/SeenDroid(30939): Get view 0 
D/SeenDroid(30939): Get view 1 
D/SeenDroid(30939): Get view 2 
D/SeenDroid(30939): Get view 3 
D/SeenDroid(30939): Get view 4 
D/SeenDroid(30939): Get view 5 
D/SeenDroid(30939): Get view 6 
D/SeenDroid(30939): Get view 7 
D/SeenDroid(30939): Get view 8 
D/SeenDroid(30939): Get view 0 
D/SeenDroid(30939): Get view 16 

Saluti, ProgVal

risposta

32

Prova questo:

public View getView(int position, View convertView, ViewGroup parent) { 

    if (null == convertView) { 
     LinearLayout view = (LinearLayout) LinearLayout.inflate(this.context, 
      R.layout.message, null); 
     Log.d("SeenDroid", String.format("Get view %d", position)); 
     TextView title = new TextView(view.getContext()); 
     title.setText(this.items.get(position).getTitle()); 
     view.addView(title); 
     return view; 
    } else { 
     LinearLayout view = (LinearLayout) convertView; 
     TextView title = (TextView) view.getChildAt(0); 
     title.setText(this.items.get(position).getTitle()); 
     return convertView; 
    } 
} 

Spiegazione: hai i duplicati perché le liste su oggetti riutilizzo dell'interfaccia utente Android. Si prevede di riutilizzare convertView anziché crearne uno nuovo se non è nullo. Ovviamente, sei responsabile di impostare un valore appropriato per l'istanza che viene riutilizzata. Altrimenti il ​​valore viene lasciato dall'ultimo "utilizzo".

+0

Ok, ho capito. Ho pensato che fosse solo il riutilizzo dell'oggetto per lo stesso oggetto, e non altri. Tuttavia, la barra di scorrimento ora diventa sempre più piccola quando si scorre, a seconda dell'altezza dell'elemento attualmente visualizzato. –

+0

@Arhimed Può spiegare la parte "Spiegazione" in maggior dettaglio. Sono bloccato con questo problema da molto tempo. – AbhishekB

+1

@abhishekb: si prega di controllare questo per i dettagli - http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ –

0

Un suggerimento: aggiungere un'istruzione di registro dopo title.setText e scrivere il valore ottenuto da getTitle(). Potresti sapere perché stai ricevendo voci duplicate.

2

ListView non garantisce l'univocità degli articoli aggiunti. È una tua responsabilità Si sta utilizzando ArrayList per memorizzare gli articoli e può memorizzare il numero di elementi duplicati che si desidera.

Se si vuole rimosso i duplicati mettere i tuoi oggetti in set e poi in lista di nuovo:

listMessages = new ArrayList<Messages>(new LinkedHashSet<Message>(listMessages))

Il LinkedHashSet sarà rimuovere i duplicati conservando l'ordine iniziale di elementi, ArrayList permetterà elementi di accesso in base alla posizione.

4
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) context 
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View gridView; 
    if (convertView == null) { 
     gridView = new View(context); 
    } else { 
     gridView = (View) convertView; 
    } 
    gridView = inflater.inflate(R.layout.worker_listmain, null); 
    // your source code here!!! Run 100% 
    // I got this problem also, I found out the way to solve it! 
    // Please use my source code :D SIMPLE is PERFECT :D 
    return gridView; 
} 
Problemi correlati