在多文件下载中更新列表视图中的进度条

11

如何在ListView中更新进度条。每个进度条都与通过AsyncTask完成的文件下载相关。

特性如下:

  1. 每个进度条都将根据下载进度进行更新。
  2. 当一个文件下载完成后,它将保存到SD卡中。
  3. 它将被添加到在后台运行的服务中。
  4. 当一个文件下载完成时,应该显示“已完成”(不应从ListView中删除)。

我还使用了一个数据库来下载文件。列表也依赖于数据库向量。我应该如何实现它。我也尝试过,但没有得到解决方案。

以下是两张详细描述的截图:

enter image description here

我也尝试了这段代码:

temp = databaseHandler.getAllNotifyNumber();
list_download = (ListView) findViewById(R.id.list_download);
myCustomAdapter = new MyCustomAdapter(mContext);
list_download.setAdapter(myCustomAdapter);
myCustomAdapter.notifyDataSetChanged();

for (int index = 0; index < temp.size(); index++) {
    String url = "http://upload.wikimedia.org/wikipedia/commons/0/05/Sna_large.png";
    grabURL(url);
}

这是AsyncTask方法:

  public void grabURL(String url) {
    new GrabURL().execute(url);
}

private class GrabURL extends AsyncTask<String, Integer, String> {

    protected String doInBackground(String... urls) {

        String filename = "MySampleFile.png";
        File myFile = new File(directory, filename);

        try {
            URL url = new URL(urls[0]);
            URLConnection connection = url.openConnection();
            connection.connect();
            int fileSize = connection.getContentLength();

            InputStream is = new BufferedInputStream(url.openStream());
            OutputStream os = new FileOutputStream(myFile);

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = is.read(data)) != -1) {
                total += count;
                publishProgress((int) (total * 100 / fileSize));
                os.write(data, 0, count);
            }

            os.flush();
            os.close();
            is.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return filename;

    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        // home_countprogress.setVisibility(View.VISIBLE);
        // home_countprogress.setText(String.valueOf(progress[0]) + "%");
        // progressbar_horizontal.setProgress(progress[0]);
        myCustomAdapter.notifyDataSetChanged();
    }

    @Override
    protected void onCancelled() {
        Toast toast = Toast.makeText(getBaseContext(),
                "Error connecting to Server", Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();

    }

    @Override
    protected void onPostExecute(String filename) {
        // progressbar_horizontal.setProgress(100);
        // home_countprogress.setVisibility(View.VISIBLE);
    }

    protected void onPreExecute() {
        // progressbar_horizontal.setVisibility(View.VISIBLE);
        // progressbar_horizontal.setProgress(0);
        // home_countprogress.setVisibility(View.VISIBLE);

        myCustomAdapter = new MyCustomAdapter(mContext);

    }
}

你按照下面的解决方案解决了这个问题吗?如果是,请告诉我,因为我也遇到了同样的实现问题。在我的情况下,还有一个“全部下载”按钮,应该同时显示每个列表视图项的多个旋转进度条。 - Sdr
2个回答

2

不要在每次进度改变时都通知您的适配器(这是一直在发生的),这样会非常低效,您可以尝试进行以下操作。

  • 为ListView中的每一行创建一个自定义视图。
  • 添加一个名为“setData()”或其他名称的方法。在适配器的getView()回调中调用它,为该视图设置数据。
  • 在“setData()”内部,将该视图注册为异步任务的进度更新的侦听器。
  • 在自定义视图中重写onStartTemporaryDetach()和onDetachedFromWindow()。确保您从异步任务更新中注销(否则您将会出现内存泄漏)。
  • 在您的异步任务中,只需通知所有已注册的侦听器即可(这些侦听器可能保存在一个url到listener的映射中或类似的内容中)。

0

不要使用ListView,尝试这个:

创建一个包含你的内容和进度条的布局,它会看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp">

<TextView
    android:id="@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/image"
    android:visibility="gone" />

</LinearLayout>

在您的活动/片段布局中,将ListView替换为具有与您的ListView相同属性的LinearLayout(或ScrollView内的LinearLayout):

<ScrollView
    android:id="@+id/scrollView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    </LinearLayout>
</ScrollView

在您的活动中创建一个函数:
private void addMyView(String url){
     LayoutInflater mInflater   = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     View mView                 = mInflater.inflate(R.layout.my_layout, null, false);
     ProgressBar mBar           = (ProgressBar) mView.findViewById(R.id.progress);

     container.addView(mView);

     grabURL(url); // starting your task here

}

还有别忘了你的LinearLayout:

LinearLayout container          = (LinearLayout) findViewById(R.id.container);

那么:

for (int index = 0; index < temp.size(); index++) {
    String url = "http://upload.wikimedia.org/wikipedia/commons/0/05/Sna_large.png";
    addMyView(url);`enter code here
}

希望能有所帮助 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接