如何在GridView / ListView的每个元素上更新ProgressBar的状态?



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

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

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

还有其他方法吗?我应该抛弃AdapterViews并使用其他东西吗?

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

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

-GridView有一个"getChildAt",你可以用它来抓取特定索引处的视图。
-如果视图不可见,更新它就没有意义了。如果它不在getFirstVisiblePosition()和getLastVisiblePosition()之间,忽略它,当它被重新绘制时,它将被绘制更新的数据。

我已经在一个项目中这样做了。如果你使用的是不带. notifydatasetchanged()的asynsctask,你可以更新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);
}

最新更新