Home » Android » android – Update progress bar in listview for multi files download

android – Update progress bar in listview for multi files download

Posted by: admin May 14, 2020 Leave a comment

Questions:

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

    }
}
How to&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).

Answer:

Instead of using ListView try this :

create a layout that contain your stuff + ProgresseBar it will seems like that

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

and in the layout of your activity/fragment replace your ListView by a LinearLayout (or LinearLayout inside a ScrollView) with the same properties as your 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

and in your activity create a function :

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

}

Also don’t forget your LinearLayout :

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

then :

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
}

Hope that help 🙂