我使用异步任务加载自定义列表视图。
我展示了一个加载diaglog。
运行doInBackground
以收集所需的所有内容。
然后onPostExecute
我这样做是为了展示ListView
中的所有内容:
adapter = new ImageAdapter(this, pix, paths);
lstView.setAdapter(adapter);
哪个工作正常,但我希望ListView逐步更新,而不是在异步任务完成时更新。所以应该没有对话框,用户应该只看到ListView逐行填充。
这是我的doInBackground
,我需要更改什么才能让ListView动态更新,而不是最后更新。
@Override
protected Boolean doInBackground(DbxFileSystem... params) {
try {
DbxFileSystem fileSystem = params[0];
for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) {
String filename = fileInfo.path.getName();
try{
if(!fileInfo.isFolder)
{
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
pix.add(image);
paths.add(fileInfo.path);
}
else
{
//must be a folder if it has no thumb, so add folder icon
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.dbfolder);
pix.add(image);
paths.add(fileInfo.path);
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.gc();
}
}
catch (Exception e) {
e.printStackTrace();
return false;
} finally {
loadingDialog.dismiss();
}
return true;
}
我需要通过再次调用它来将适配器重新绑定到ListView吗?
lstView.setAdapter(adapter);
或者你绑定它一次然后适配器的任何更新将显示在列表视图中吗?
[编辑]以下是尝试使用notifyDataSetChange
d的新代码(但由于某种原因,我的自定义列表视图中没有显示任何内容)
这是onCreate,它创建适配器,设置初始值(将是空数组),然后将适配器绑定到listview。
lstView = (ListView) findViewById(R.id.lstView);
adapter = new ImageAdapter(this, pix, paths);
lstView.setAdapter(adapter);
在我的doInBackground
asynctask中,我正在调用publishProgress(1);在循环。我发送的值为'1',但未使用。
publishProgress(1);
Finall,我有onProgressUpdate,它正在使用notifyDataSetChanged,但它没有做任何事情。它不会更新列表视图。
@Override
protected void onProgressUpdate(Integer...progress) {
adapter.notifyDataSetChanged();
super.onProgressUpdate(progress);
}
答案 0 :(得分:2)
您不需要重新绑定适配器。只需通过调用" adapter.notifyDataSetChanged()"来通知视图数据已被更改。另请注意,您不应该在doInBackground()中调用它或任何其他UI操作。您要么在doInBackground中检索所有内容,将其作为结果返回,然后在onPostExecute中调用notifyDataSetChanged,要么使用publishProgress()并在onProgressUpdate()中调用notifyDataSetChanged。
由于您希望" ListView能够即时更新,而不是最终更新"像这样使用publishProgress()和onProgressUpdate():
@Override
protected Boolean doInBackground(DbxFileSystem... params) {
try {
DbxFileSystem fileSystem = params[0];
for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) {
String filename = fileInfo.path.getName();
try{
if(!fileInfo.isFolder)
{
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
pix.add(image);
paths.add(fileInfo.path);
publishProgress(1);
}
else
{
//must be a folder if it has no thumb, so add folder icon
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.dbfolder);
pix.add(image);
paths.add(fileInfo.path);
publishProgress(1);
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.gc();
}
}
catch (Exception e) {
e.printStackTrace();
return false;
} finally {
// loadingDialog.dismiss();
}
return true;
}
}
@Override
protected void onProgressUpdate(Integer... progress) {
//check log if paths and pix are updated
//Log.d("paths_size", String.valueOf(paths.size());
//Log.d("pix_size", String.valueOf(pix.size());
adapter.notifyDataSetChanged();
lstView.requestLayout();
//if notifyDataSetChanged() fails try the ff:
//lstView.setAdapter(null);
//lstView.setAdapter(new ImageAdapter(this, pix, paths);
super.onProgressUpdate(progress);
}
答案 1 :(得分:1)
向适配器添加数据时,必须调用:
notifyDataSetChanged();
(通知附加的观察者基础数据已被更改,反映数据集的任何视图都应自行刷新。)
答案 2 :(得分:0)
致电adapter.notifyDataSetChanged();
。如果您重新加载列表而不是仅添加元素,则可以调用list.clear(); list.add(newList); adapter.notifyDataSetChanged();