11

Ich verwende einen ArrayAdapter, um Elemente zu einem benutzerdefinierten ListView hinzuzufügen und die Ergebnisse in meiner Android App anzuzeigen. Das Problem, das ich habe, ist, dass der ArrayAdapter zu warten scheint, bis alle Elemente darin sind, bevor es die Ansicht anzeigt. Das heißt, wenn ich die Elemente zum ArrayAdapter hinzufüge und notifyDataSetChanged aufruft, wird die ListView nicht aktualisiert, um das hinzugefügte Element anzuzeigen. Es wartet, bis alle Elemente hinzugefügt sind und GetView aufgerufen wird, bevor die Elemente angezeigt werden.Android - Hinzufügen und Anzeigen von Elementen zu ListView nacheinander mit einem ArrayAdapter

Was ich möchte, ist es, das Element sofort nach dem Hinzufügen zum ListView anzuzeigen. Ist das möglich?

Ich glaube, der entsprechende Code ist folgende:

r_adapter = new ReminderAdapater(Activity_ContentSearch.this, R.layout.search_listitem, myList); 
listView.setAdapter(r_adapter); 
... 
r_adapter.notifyDataSetChanged(); 
r_adapter.clear(); 
for(int i = 0; i < myList.size(); i++) 
{ 
    r_adapter.add(myList.get(i)); 
    r_adapter.notifyDataSetChanged(); 
} 

Wie Sie sehen können, obwohl ich notifyDataSetChanged nach der Methode add nenne, ist es nicht eigentlich die Ansicht zu aktualisieren. Nachdem die obige Schleife beendet ist, wird die Ansicht schließlich aktualisiert (basierend auf dem, was ich weiß, weil GetView erst aufgerufen wird, nachdem dieser Abschnitt des Codes fertig ist).

Ich habe versucht, die Add-Methode meiner benutzerdefinierten ArrayAdapter ohne Glück zu überschreiben, da ich keinen Zugriff auf die Ansicht in dieser Methode haben.

Jede Hilfe wäre willkommen :)

Bara

Antwort

23

Android UI sein ist single-threaded. Wenn Sie dem Adapter einen Eintrag hinzufügen, geben Sie dem Hauptanwendungsthread die Kontrolle nicht mehr an Android zurück. Daher hat Android keine Chance, Ihre Einträge anzuzeigen, bis Sie die Kontrolle zurückgegeben haben, und Sie tun das erst, wenn Sie Ihren Adapter vollständig gefüllt haben.

Here is an example zeigt die Verwendung einer AsyncTask, um eine ArrayAdapter progressiv über einen Hintergrund-Thread zu füllen.

/*** 
    Copyright (c) 2008-2012 CommonsWare, LLC 
    Licensed under the Apache License, Version 2.0 (the "License"); you may not 
    use this file except in compliance with the License. You may obtain a copy 
    of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required 
    by applicable law or agreed to in writing, software distributed under the 
    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
    OF ANY KIND, either express or implied. See the License for the specific 
    language governing permissions and limitations under the License. 

    From _The Busy Coder's Guide to Android Development_ 
    http://commonsware.com/Android 
*/ 

package com.commonsware.android.async; 

import android.app.ListActivity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.widget.ArrayAdapter; 
import android.widget.Toast; 
import java.util.ArrayList; 

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); 
    } 

    @SuppressWarnings("unchecked") 
    @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(); 
    } 
    } 
} 
Verwandte Themen