Как заполнить listview асинхронно?
Мне интересно, как я должен реализовать ListAdapter
, который асинхронно загружает свои представления в ListView
? Я хочу сделать это, потому что я заполняю список информацией из моей базы данных, что делает мою деятельность немного медленной, чтобы загружать время от времени.
Ответы
Ответ 1
Вы можете использовать AsyncTask
и использовать onPostExecute
для публикации недавно загруженных результатов:
private ArrayAdapter adapter = new YourArrayAdapter();
private class YourAsyncTask extends AsyncTask<Void, Void, List<YourItem>> {
@Override
protected void onPreExecute() {
// start loading animation maybe?
adapter.clear(); // clear "old" entries (optional)
}
@Override
protected List<YourItem> doInBackground(Void... params) {
// everything in here gets executed in a separate thread
return DataBase.getItems();
}
@Override
protected void onPostExecute(List<YourItem> items) {
// stop the loading animation or something
adapter.addAll(items);
}
}
Ответ 2
Лучший подход, который я видел до сих пор, - это CommonsWare. Он был найден в этом связанном ответе.
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();
}
}
}
Ответ 3
Проще всего использовать AsyncTask для загрузки и вызова publishProgress
по мере загрузки каждого элемента (или, если вы хотите загрузить все элементы и вывести их все сразу, обновите пользовательский интерфейс в onPostExecute
Ответ 4
Возможно, что .notifyDataSetChanged() возможно, что вы после? Каждый раз, когда вы добавляете новый элемент в список, который поддерживает ArrayAdapter, вы можете вызвать .notifyDataSetChanged() в этом экземпляре адаптера, чтобы сообщить ему об обновлении. Таким образом, ListView может постепенно наращивать и отображать каждый элемент, поскольку они добавляются в список.
Ответ 5
Использовать AsyncTask.
Это поможет вам восстановить данные в фоновом режиме.
Ответ 6
С библиотеками расширений Kotlin и Kotlin эта задача стала проще. Вы можете использовать конструкцию doAsync/uiThread в библиотеке Anko с долей кода. В приведенном ниже руководстве по ссылкам я использую эту библиотеку для заполнения списка ListView котировками акций, которые вызывают API REST асинхронно с Kotlin. Kotlin полностью интегрирован в Android Studio:
http://www.todroid.com/creating-a-stock-pricing-application-with-kotlin-for-android/