如何异步向列表视图添加行?

时间:2012-08-16 21:06:12

标签: android android-listview android-asynctask android-fragments android-arrayadapter

我需要使用来自网络的数据填充一个长ListView,比如说整个数据收集需要2-3秒。我不希望用户看到加载Dialog并等待整个列表下载。相反,我希望在每个项目可用时更新ListView

  • 我该怎么做?
  • 我想通过添加ArrayAdapter AsyncTaskOnProgressUpdate
  • 来推测
  • 我必须在每个添加的行后发出notifyDatasetChanged()吗?
  • Fragment / Loader方法更好吗?
  • 是否有针对案例的教程或API演示参考实现 像这样?

Activity死亡之前完全取出数据并不重要(即Service是不必要的)

3 个答案:

答案 0 :(得分:3)

到目前为止,我见过的最佳方法是CommonsWare。在相关的answer中找到了它。

显然,没有add调用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();
    }
  }
}

答案 1 :(得分:0)

我想你可以从这里开始:http://www.vogella.com/articles/AndroidPerformance/article.html

因此,您需要对服务器进行异步调用以获取数据。 或者你可以为此运行后台任务。

您可以使用Google AsyncTask或在此处搜索stackoverflow。 以下是示例:AsyncTask Android example

答案 2 :(得分:0)

为了确保,ListView的{​​{1}}及其基础数据无法从UI线程以外的线程更新。必须在主应用程序线程上执行更新。 非UI线程可以使用adapterpost()等来调用更新。

这样调用runOnUiThread()并不是一种好习惯,它应该由notifyDatasetChanged()本身或更改数据的对象调用。

由于网络运行缓慢,请考虑是否不希望将下载的数据存储在Adapter中。最后使用database来实现某种CursorAdapter,最好在您的工作线程中更新Loader时,会自动通知database变化。