我怎样才能将行添加到列表视图异步?
我需要用网络中的数据填充一个长的ListView
,比如说整个数据收集需要2-3秒。 我不希望用户看到加载Dialog
并等待整个列表下载。 相反,我想在每个项目变得可用时更新ListView
。
OnProgressUpdate
从AsyncTask
添加到ArrayAdapter
? notifyDatasetChanged()
吗? Fragment
/ Loader
方法更好吗? 数据在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();
}
}
}
只是为了确保ListView
的adapter
及其底层数据不能从UI线程以外的线程更新。 必须在主应用程序线程上执行更新。 非UI线程可以使用post()
或runOnUiThread()
等来调用更新。
像这样调用notifyDatasetChanged()
并不是一个好习惯,它应该由Adapter
本身或改变数据的对象调用。
由于网络运行缓慢,请考虑将下载的数据存储在database
是否可取。 比你最终实现某种CursorAdapter
,最好是使用Loader
,以便当你在工作线程中更新database
时, ListView
会自动通知有关更改。
我想你可以从这里开始:http://www.vogella.com/articles/AndroidPerformance/article.html
所以,您需要对服务器进行异步调用以获取数据。 或者你可以运行一个后台任务。
你可以谷歌的AsyncTask
或在这里搜索stackoverflow。 以下是示例:AsyncTask Android示例
上一篇: How can I add rows to a listview asynchronously?
下一篇: Queries in MongoDB