目前我有一个GridView,每个元素都应该有一个单独的ProgressBar。这些元素表示单独的下载,我想使用这些ProgressBars显示下载的状态。
但是我应该如何更新它们呢?我的问题是,根据文档(以及我在Google IO视频中听到的),更新AdapterViews中的元素的唯一方法是更新分配的适配器,并在每次更新后调用.notifyDatasetChanged()。
当然,这在这种情况下也是有效的,但更新相当频繁(每秒5-10次更新)。以这种频率调用.notifyDatasetChanged会中断与GridView的任何交互。例如,用户试图长时间点击网格中的项目,但点击事件停止,因为调用了.notifyDatasetChanged来更新下载进度。
有没有其他方法可以做到这一点?我应该抛弃AdapterViews而使用其他东西吗?
发布于 2011-11-15 07:55:33
对于像您这样的频繁更新(每秒多次)的情况,notifyDatasetChanged不是正确的方法-您需要直接更新单个视图。
如果看不到您的代码以及文件下载和GridView中的条目之间的关系,就很难确切地说出您需要什么调用,但是:
-GridView有一个"getChildAt“,您可以使用它来获取特定索引处的视图。
-如果视图甚至不可见,那么更新视图就没有意义了。如果它不在getFirstVisiblePosition()和getLastVisiblePosition()之间,请忽略它,每当它被重新绘制时,它都将使用更新的数据进行绘制。
发布于 2011-11-14 17:29:26
我已经在一个项目中做到了这一点。如果您正在使用不带.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);
}https://stackoverflow.com/questions/8118433
复制相似问题