Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update progressbar in a ListView item

I have a ListView attached to an ArrayAdapter. When the user clicks a download button for an item in the ListView a download starts using the DownloadManager.

What I want to do is to track the download progress with a progress bar (placed in the item layout). How can this be achieved?

The way Pocket Cast does it is exacly what I'm after:

Pocket Cast exampel http://www.mrcrab.net/images/thumb_big/9982-Pocket_Casts_Apk_v4.3.2_Android-0.jpg

Note: I know how to work with the DownloadManager, it's the instant update of the progress bar that is tricky.

like image 639
Mike Avatar asked Oct 30 '13 16:10

Mike


People also ask

How do you change how much of the progress bar is filled in?

By default, the progress bar is full when the progress value reaches 100. You can adjust this default by setting the android:max attribute. Other progress bar styles provided by the system include: Widget.

How to set progress bar in android?

In android there is a class called ProgressDialog that allows you to create progress bar. In order to do this, you need to instantiate an object of this class. Its syntax is. ProgressDialog progress = new ProgressDialog(this);

What are the different types of progress bars?

There are 2 types of progress bars: determinate and indeterminate. The former is used when the amount of information that needs to be loaded is detectable. The latter is used when the system is unsure how much needs to be loaded or how long it will take.


1 Answers

This is the way I finally solved it (after many iterations and different implementations). It's a bit tricky but basically you need three things:

  1. An AsyncTask that gathers meta data
  2. A scroll listener that tells us when the user has stopped scrolling/flinging
  3. A clever algorithm that finds any visible row that needs updating and asks the adapter to only update that specific row

This is the way I designed and implemented it:

Screenshot

I wrote in more detail about it here, and please see the github code for the complete imlementation.

    private class UpdaterAsyncTask extends AsyncTask<Void, Void, Void> {

    boolean isRunning = true;

    public void stop() {
        isRunning = false;
    }

    @Override
    protected Void doInBackground(Void... params) {

        while (isRunning) {

            // Gather data about your adapter objects
            // If an object has changed, mark it as dirty                

            publishProgress();

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Void... params) {
        super.onProgressUpdate();

        // Update only when we're not scrolling, and only for visible views
        if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
            int start = mListview.getFirstVisiblePosition();
            for(int i = start, j = mListview.getLastVisiblePosition(); i<=j; i++) {
                View view = mListview.getChildAt(i-start);
                if (((Content)mListview.getItemAtPosition(i)).dirty) {
                    mListview.getAdapter().getView(i, view, mListview); // Tell the adapter to update this view
                }

            }
        }

      }
    }
like image 134
Mike Avatar answered Sep 30 '22 02:09

Mike