我使用的是带有自定义列表行的ListView,其中每个ListItem都有ProgressBar。
当用户单击ImageView时,应用程序启动一个AsyncTask从远程服务器下载文件,并更新进度条中的进度。
我使用并行异步任务,这意味着应用程序可以启动多个下载并在每一行的ProgressBar中更新它们。
这是密码‘
static class ViewHolder {
protected TextView title;
protected TextView size;
protected TextView version;
protected ImageView appIcon;
protected ProgressBar progressBar;
}
public class UpdateAdapter extends ArrayAdapter<UpdateItem> {
public UpdateAdapter(Context context, ArrayList<UpdateItem> users) {
super(context, 0, users);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
UpdateItem updateItem = getItem(position);
View v = convertView;
ViewHolder viewHolder;
LayoutInflater mInflater = LayoutInflater.from(getContext());
if (convertView == null) { // if convertView is null
convertView = mInflater.inflate(R.layout.row, null);
viewHolder = new ViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.apptitlelabel);
viewHolder.version = (TextView) convertView.findViewById(R.id.versionlabel);
viewHolder.size = (TextView) convertView.findViewById(R.id.sizelabel);
viewHolder.appIcon = (ImageView) convertView.findViewById(R.id.appicon);
viewHolder.progressBar = (ProgressBar) convertView.findViewById(R.id.downloadProgressBar);
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) v.getTag();
viewHolder.progressBar.setProgress(0);
View finalConvertView = convertView;
viewHolder.appIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DownloadFileFromURL task = new DownloadFileFromURL();
task.position = position;
task.v = finalConvertView;
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, updateItem.downloadlink);
}
});
return convertView;
}
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
**/
int position;
View v;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* Downloading file in background thread
**/
@Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
String fileExtenstion = MimeTypeMap.getFileExtensionFromUrl(url.getPath());
String fname = URLUtil.guessFileName(url.getPath(), null, fileExtenstion);
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString() + "/" + fname);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
**/
protected void onProgressUpdate(String... progress) {
// setting progress percentage
// Log.w(TAG, progress[0]);
updateStatus(position, Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
**/
@Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
Log.w(TAG, "onPostExecute: ");
removeListItem(v, position);
}
}
public void updateStatus(int index, int Status) {
int in = index - updateLv.getFirstVisiblePosition();
View v = updateLv.getChildAt(in);
ProgressBar progress = (ProgressBar) v.findViewById(R.id.downloadProgressBar);
progress.setProgress(Status);
}问题是,当用户启动两次下载(比如点击第一次第二次图像视图),第一次任务已经完成,第一行从列表中删除(在onPostExecute中),现在,第二行变为第一行,但是任务更新当前的第二行(这是删除第一项之前的第三行).
我知道这是因为我传入了updateStatus,要更新项目的位置,但是在此期间,ListView更改并删除项目(因为它们的下载已经完成),但是我没有当前的解决方案。
我甚至尝试将ProgressBar对象引用传递给updateStatus方法,而不是使用item位置,并且我认为这样可以解决problem...but没有运气:)
我也试着追踪物品的位置,但hashmap..with没有成功.:)
发布于 2022-07-06 15:33:18
removeListItem(v, position);中也存在问题,在您的示例中将删除第一项和第三项。为了解决这个问题,尝试为每个条目提供一个唯一的ID,您可以在您的UpdateItem类中添加一个字段,在这里,我演示了一个单独的ArrayList。
公共UpdateAdapter(上下文,ArrayList用户){超级(上下文,0,用户);resetIds(users.size());} ArrayList arrayIds =新的ArrayList<>();ArrayList arrayIds (int大小){ arrayIds.clear();for (int i= 0;i< size;i++) arrayIds.add(String.valueOf(i));}
之前添加task.id = arrayIDs.get(position);
在onProgressUpdate中添加字段String id;、更改方法onProgressUpdate和onPostExecute.
保护的onProgressUpdate(字符串.(进度){ //设置进度百分比// Log.w(标记,进度);// updateStatus(位置,Integer.parseInt(进度));updateStatus(id,Integer.parseInt(进度));}@覆盖受保护的无效onPostExecute(String file_url) { //在文件下载后关闭对话框Log.w(标签,"onPostExecute:");removeListItem(v,位置);//问题,稍后自行修复arrayIds.remove(id);}
updateStatus
公共updateStatus(String id,int Status) { int index = arrayIds.indexOf(id);int in = index - updateLv.getFirstVisiblePosition();View v= updateLv.getChildAt(in);ProgressBar progress = (ProgressBar) v.findViewById(R.id.downloadProgressBar);progress.setProgress(Status);}
在onPostExecute,中添加代码arrayIds.remove(id);时,可以更好地使用ArrayList of Integer for arrayIds,但需要小心--请确保选择了remove(object o),而不是remove(int index)。如果这有效,那么使用相同的appoach来修复removeListItem.。
https://stackoverflow.com/questions/72882841
复制相似问题