Как заполнить 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/