7

Ich muss eine lange ListView mit Daten aus dem Netzwerk bevölkern, sagen 2-3 Sekunden für die gesamte Datensammlung. Ich möchte nicht, dass der Benutzer eine Lade Dialog sehen und auf den gesamten Download der Liste warten. Stattdessen möchte ich die ListView aktualisieren, wie jedes Element verfügbar wird.Wie kann ich Zeilen zu einer Listenansicht asynchron hinzufügen?

  • Wie kann ich das tun?
  • nehme ich an, indem ich zu ArrayAdapter von AsyncTask mit OnProgressUpdate hinzufüge?
  • Muss ich nach jeder hinzugefügten Zeile einen notifyDatasetChanged() ausgeben?
  • Ist die /Loader Annäherung besser?
  • Gibt es eine Tutorial- oder API-Demo-Referenzimplementierung für einen Fall so?

Es ist nicht wichtig, dass die Daten vollständig vor den Activity Gesenke geholt werden (dh Service ist nicht erforderlich)

+0

Verwendung ein ListFragment von Support-Bibliothek, bei Proben suchen, Cache-Daten in einem privaten Feld dann notifyDatasetChanged aufrufen, wenn ein neues Element bereit ist – sherpya

+0

„langsam“ definieren. Holen Sie sich in großen Abständen oder ist es ein großer Download selbst? –

Antwort

3

Der beste Ansatz, den ich bisher gesehen habe, ist von CommonsWare. Es wurde in diesem verwandten answer gefunden.

Anscheinend ist nichts falsch mit dem Aufruf add ohne notifyDatasetChanged().

public class AsyncDemo extends ListActivity { 
    private static final String[] items={"lorem", "ipsum", "dolor", 
             "sit", "amet", "consectetuer", 
             "adipiscing", "elit", "morbi", 
             "vel", "ligula", "vitae", 
             "arcu", "aliquet", "mollis", 
             "etiam", "vel", "erat", 
             "placerat", "ante", 
             "porttitor", "sodales", 
             "pellentesque", "augue", 
             "purus"}; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    setListAdapter(new ArrayAdapter<String>(this, 
         android.R.layout.simple_list_item_1, 
         new ArrayList<String>())); 

    new AddStringTask().execute(); 
    } 

    class AddStringTask extends AsyncTask<Void, String, Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 
     for (String item : items) { 
     publishProgress(item); 
     SystemClock.sleep(200); 
     } 

     return(null); 
    } 

    @Override 
    protected void onProgressUpdate(String... item) { 
     ((ArrayAdapter<String>)getListAdapter()).add(item[0]); 
    } 

    @Override 
    protected void onPostExecute(Void unused) { 
     Toast 
     .makeText(AsyncDemo.this, "Done!", Toast.LENGTH_SHORT) 
     .show(); 
    } 
    } 
} 
0

Ich denke, man kann hier beginnen: http://www.vogella.com/articles/AndroidPerformance/article.html

So, müssen Sie einen asynchronen Anruf zu einem Server für Daten. Oder Sie könnten eine Hintergrundaufgabe dafür ausführen.

Sie können für AsyncTask Google oder suchen Sie hier auf Stackoverflow das. Hier ist Beispiel: AsyncTask Android example

+0

Welcher dieser beiden Links zeigt, wie man einzelne Zeilen asynchron hinzufügt und nicht wartet, bis alle Zeilen gefüllt sind? Ich sehe nichts über diese Links, die die Frage beantworten. –

+0

In den Links ist Information, wie man einen Job im Hintergrundthread macht. Und es gibt einige Informationen, wie man GUI aktualisiert. Sie können GUI-Elemente nicht aus Hintergrundthreads aktualisieren. Im zweiten Link ist ein Beispiel mit TextView. – Guntis

0

Nur um sicher zu machen, ListView ‚s adapter noch die zugrunde liegenden Daten nicht von anderen Thread als dem UI-Thread aktualisiert werden. Updates müssen im Hauptanwendungs-Thread ausgeführt werden. Nicht-UI-Threads können post() oder runOnUiThread() usw. verwenden, um ein Update aufzurufen.

Aufruf notifyDatasetChanged() einfach so ist eher nicht gute Praxis, sollte es von der Adapter selbst oder das Objekt, das die Daten ändern aufgerufen werden.

Da der Netzwerkbetrieb langsam ist, überlegen Sie, ob es nicht wünschenswert wäre, heruntergeladene Daten in database zu speichern. Dann enden Sie mit der Implementierung einer Art von CursorAdapter, am besten mit der Verwendung von Loader, so dass, wenn Sie database in Ihrem Arbeitsthread aktualisieren, wird ListView automatisch über die Änderungen benachrichtigt werden.

+0

Ich frage speziell über die Anzeige der Daten und die Aktualisierung der 'ListView', wie es verfügbar wird, nicht im Voraus erfassen und speichern. –

+0

Wenn Ihr Artikel verfügbar ist, fügen Sie ihn in 'Datenbank' ein und' ListView' wird über die Änderung informiert, in diesem Fall, dass der erwähnte Artikel hinzugefügt wurde, es sei denn, Sie fügen nicht alle Artikel in einer Transaktion ein. – biegleux