Android - Hinzufügen und Elemente Listview einer nach dem anderen zeigt eine ArrayAdapter mit
-
22-09-2019 - |
Frage
Ich verwende eine ArrayAdapter um einen Artikel in einem benutzerdefinierten Listview hinzufügen und die Ergebnisse in meinem Android-App zeigt. Das Problem, das ich habe, ist, dass die ArrayAdapter, bis alle Elemente darin sind, zu warten scheint, bevor es die Ansicht zeigt. Das heißt, wenn ich hinzufüge, die Einzelteile zum ArrayAdapter und ich rufe notifyDataSetChanged, ist es nicht das Listview aktualisiert den zusätzlichen Punkt zu zeigen. Er wartet, bis alle Elemente hinzugefügt werden und GetView wird aufgerufen, bevor die Elemente zeigt.
Was möchte ich es zu tun ist, um das Element zu zeigen, sofort nachdem sie auf das Listview-Zugabe. Ist das möglich?
Ich glaube, dass der entsprechende Code ist die 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 aktualisieren. Nachdem es die obige Schleife beendet hat sich die Meinung schließlich aktualisiert wird (basierend auf, was ich weiß, das ist, weil GetView erst nach diesem Abschnitt des Codes aufgerufen wird, wird durchgeführt).
Ich habe versucht, die Add-Methode meines benutzerdefinierten ArrayAdapter ohne Glück außer Kraft zu setzen, da ich keinen Zugriff auf die Ansicht in diesem Verfahren.
Jede Hilfe wäre willkommen:)
Bara
Lösung
Android UI ist single-threaded. Sie geben nicht die Kontrolle zurück zu Android aus dem Hauptanwendungsthread jedes Mal, wenn Sie einen Eintrag an den Adapter hinzufügen. Daher ist Android nicht die Chance bekommen, Ihre Einträge angezeigt werden, bis Sie die Kontrolle zurück und Sie tun das nicht, bis Sie Ihren Adapter in seiner Gesamtheit bevölkert haben.
Hier ist ein Beispiel die Verwendung eines zeigt AsyncTask
ein 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();
}
}
}