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

时间:2013-12-24 12:43:42

标签: android android-listview android-asynctask download android-progressbar

我们如何更新ListView中的进度条。当每个进度条与文件下载相关联时,通过AsyncTask完成。

该功能将是:

  1. 每个进度条都会在下载过程中更新。
  2. 当文件完成下载后,它将保存到SD卡中。
  3. 将添加它服务(在后台运行。
  4. 当下载一个文件时,它应显示“完成”(不应删除表单列表视图)
  5. 我还使用数据库下载文件。该列表还取决于数据库向量。我该如何实现它。我也试过但没有得到解决方案。

    下面是两个详细描述的屏幕截图:

    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 mathod:

      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);
    
        }
    }
    

2 个答案:

答案 0 :(得分:2)

您可以尝试执行以下操作,而不是每次进度更改时通知您的适配器(这是所有时间)并使其完全无效。

  • 为ListView
  • 中的每一行创建自定义视图
  • 添加一个名为'setData()'的方法。在适配器的getView()回调中调用它,设置该视图的数据。
  • 在'setData()'内部注册该视图,作为异步任务进度更新的侦听器。
  • 在自定义视图中覆盖onStartTemporaryDetach()和onDetachedFromWindow()。确保从那里取消注册异步任务更新(否则你会得到内存泄漏)。
  • 在您的异步任务中,只需通知所有已注册的侦听器(可能是在侦听器或类似内容的URL地图中)。

答案 1 :(得分:0)

而不是使用ListView试试这个:

创建一个包含你的东西+ ProgresseBar的布局,它似乎就是那个

<?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>

并且在您的activity / fragment的布局中,通过LinearLayout(或ScrollView中的LinearLayout)替换ListView,其属性与listview相同:

<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
}

希望有所帮助:)