首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >管理ListViewItem进度条行更新的Android

管理ListViewItem进度条行更新的Android
EN

Stack Overflow用户
提问于 2022-07-06 11:30:18
回答 1查看 38关注 0票数 0

我使用的是带有自定义列表行的ListView,其中每个ListItem都有ProgressBar。

当用户单击ImageView时,应用程序启动一个AsyncTask从远程服务器下载文件,并更新进度条中的进度。

我使用并行异步任务,这意味着应用程序可以启动多个下载并在每一行的ProgressBar中更新它们。

这是密码‘

代码语言:javascript
复制
 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没有成功.:)

EN

回答 1

Stack Overflow用户

发布于 2022-07-06 15:33:18

removeListItem(v, position);中也存在问题,在您的示例中将删除第一项和第三项。为了解决这个问题,尝试为每个条目提供一个唯一的ID,您可以在您的UpdateItem类中添加一个字段,在这里,我演示了一个单独的ArrayList。

  1. 更改适配器构造函数,添加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));}

  1. the,在执行AsynTask.

之前添加task.id = arrayIDs.get(position);

onProgressUpdate中添加字段String id;、更改方法onProgressUpdateonPostExecute.

保护的onProgressUpdate(字符串.(进度){ //设置进度百分比// Log.w(标记,进度);// updateStatus(位置,Integer.parseInt(进度));updateStatus(id,Integer.parseInt(进度));}@覆盖受保护的无效onPostExecute(String file_url) { //在文件下载后关闭对话框Log.w(标签,"onPostExecute:");removeListItem(v,位置);//问题,稍后自行修复arrayIds.remove(id);}

updateStatus

  1. Change

公共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.。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72882841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档