3

目前我有一个 GridView,每个元素都应该有一个单独的 ProgressBar。这些元素代表单独的下载,我想使用这些 ProgressBars 显示下载的状态。

但是我应该如何更新它们?我的问题是,根据文档(以及我在 Google IO 视频中听到的内容),在 AdapterViews 中更新元素的唯一方法是更新分配的适配器,并在每次更新后调用 .notifyDatasetChanged() 。

当然这在这种情况下也确实有效,但是更新非常频繁(5-10 更新秒)。并且以这种频率调用 .notifyDatasetChanged 会中断与 GridView 的任何交互。例如,用户尝试长按 Grid 中的某个项目,但单击事件停止,因为调用了 .notifyDatasetChanged 来更新下载进度。

有没有其他方法可以做到这一点?我应该放弃 AdapterViews 并使用其他东西吗?

4

2 回答 2

2

对于像您这样频繁更新(每秒多次)的情况,notifyDatasetChanged 不是正确的方法 - 您需要直接更新各个视图。

如果没有看到您的代码以及文件下载与 GridView 中的条目之间的关系,很难确切地说出您需要哪些调用,但是:

-GridView 有一个“getChildAt”,您可以使用它来获取特定索引处的视图。
- 如果视图甚至不可见,则更新视图毫无意义。如果它不在 getFirstVisiblePosition() 和 getLastVisiblePosition() 之间,请忽略它,无论何时重绘它都会使用更新的数据进行绘制。

于 2011-11-14T23:55:33.143 回答
0

我在一个项目中做到了这一点。如果您使用没有 .notifyDatasetChanged() 的 Asysctask,则可以更新 UI。例如,我的 Utils 中有一个下载方法。班级

public static String downloadFile(DownloadItem downItem, AsynBackGroundFileLoader asynBackGroundFileLoader, String fileName,
            String fileURL) {
                // Spiking my code 
            while (bufferLength = inputStream.read(buffer) > 0 ) {
                    fileOutput.write(buffer, 0, bufferLength);
                // add up the size so we know how much is downloaded
                downloadedSize += bufferLength;

                // this is where you would do something to report the progress,
                int pro = ((int) (downloadedSize * 100 / totalSize));

                asynBackGroundFileLoader.updateProgress(pro);

            }
    }

在我的 AsyncTask

public class AsynBackGroundFileLoader extends AsyncTask < Void , Integer , String > {



public AsynBackGroundFileLoader (DownloadItem dItem , TableLayout progressBarHodler , UpgradeActivity listener ) {
        try {
            mDownloadingProgressBarHolder = progressBarHodler ;
            this.mDownloadingProgressBarHolder.setVisibility ( View.VISIBLE ) ;

            mDownloadingProgressBar = ( ProgressBar ) mDownloadingProgressBarHolder.findViewById ( R.id.downloading_progress_bar ) ;
            downloadCancelButton = ( ImageButton ) mDownloadingProgressBarHolder.findViewById ( R.id.downloading_progress_cancel_btn ) ;
            downloadCancelButton.setImageResource ( R.drawable.btn_cancel );

    @ Override
    protected void onPreExecute ( ) {

    }

    @ Override
    protected String doInBackground ( Void ... params ) {

            boolean loadSuccess = Utils.downloadFile ( downItem , this , mFileName , downItem.getLink ( ) ) ;
        return ""+loadSuccess ;
    }

    @ Override
    protected void onPostExecute ( String result ) {

    }

    public void updateProgress ( int progressPercentage ) {
        try {
            if ( progressPercentage < 0 ) {
                progressPercentage = 0 ;
            } else if ( progressPercentage > 100 ) {
                progressPercentage = 100 ;
            }

//Here I am updating my UI without making list to notifyDataChanged()
                currentCompletedProgress = progressPercentage ;
                // This is my progressbar in UI that update , I got this progressbar by passing UI item view in constructor 
                mDownloadingProgressBar.setProgress ( progressPercentage ) ;
                downItem.setTotalProgress ( currentCompletedProgress ) ;
            } catch ( Exception e ) {
                Log.e ( TAG , "Exception = " + e.toString ( ) ) ;
                e.printStackTrace ( ) ;
            }

        }

    public ProgressBar getmDownloadinProgressBar ( ) {
        return mDownloadingProgressBar ;
    }
}

当用户点击列表行时我开始下载

public void onItemClick(AdapterView<?> tempadapter, View view, int position, long arg3) {
    TableLayout table = ((TableLayout) view.findViewById(R.id.downloading_progress_holder));
    DownloadItem temp = adapter.items.get(position);

        AsynBackGroundFileLoader bgdownloader = new AsynBackGroundFileLoader(temp, table, UpgradeActivity.this);
        bgdownloader.execute();
    }

    table.setVisibility(View.VISIBLE);
}
于 2011-11-14T09:29:26.487 回答