我怎样才能将行添加到列表视图异步?

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

  • 我怎样才能做到这一点?
  • 我认为通过使用OnProgressUpdateAsyncTask添加到ArrayAdapter
  • 我必须在每个添加的行之后发出notifyDatasetChanged()吗?
  • Fragment / Loader方法更好吗?
  • 是否有像这样的案例的教程或API演示参考实现?
  • 数据在Activity死亡之前完全取出并不重要(即Service不必要)


    我目前看到的最好的方法来自CommonsWare。 它被发现在这个相关的答案。

    显然没有notifyDatasetChanged()调用add没有任何问题。

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

    只是为了确保ListViewadapter及其底层数据不能从UI线程以外的线程更新。 必须在主应用程序线程上执行更新。 非UI线程可以使用post()runOnUiThread()等来调用更新。

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

    由于网络运行缓慢,请考虑将下载的数据存储在database是否可取。 比你最终实现某种CursorAdapter ,最好是使用Loader ,以便当你在工作线程中更新database时, ListView会自动通知有关更改。


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

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

    你可以谷歌的AsyncTask或在这里搜索stackoverflow。 以下是示例:AsyncTask Android示例

    链接地址: http://www.djcxy.com/p/11085.html

    上一篇: How can I add rows to a listview asynchronously?

    下一篇: Queries in MongoDB