在异步任务中更新自定义适配器

时间:2014-04-11 15:51:28

标签: android

我使用异步任务加载自定义列表视图。 我展示了一个加载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);
    }

3 个答案:

答案 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();