Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update progress bar in listview for multi files download

How can we update a progress bar in ListView. When each progress bar is associated download of a file and which is done via AsyncTask.

The feature will be:

  1. Each progress bar will be update with downloading process.
  2. When a file complete downloaded it will be save into sd card.
  3. It will be added it service(Running on the background.
  4. When one file downloaded it should show "Complete "(should not be remove form listview)

I also used a database for downloading the file.The list also depends on the database vector. How can I implement it. I also tried but did not get solution.

Below are the two screenshots to describe it in detail:

enter image description here

I also tried this code:

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

This is 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);

    }
}
like image 809
Prosanto Avatar asked Dec 24 '13 12:12

Prosanto


1 Answers

Instead of notifying your adapter every single time your progress changes (which is all the time) and making this completely inefficient you can try to do the following.

  • Create a custom view for each row in the ListView
  • Add a method there called 'setData()' or something. Call this in the getView() callback of the adapter, setting the data for that view.
  • Inside 'setData()' register that view as a listener for progress updates from the async task.
  • Override onStartTemporaryDetach() and onDetachedFromWindow() inside your custom view. Make sure you deregister from the async task updates there (else you'll get a memory leak).
  • In your async task, simply notify all the registered listeners (which are probably held in a map of urls to listeners or something like that).
like image 159
Tas Morf Avatar answered Sep 29 '22 12:09

Tas Morf