unknown apk
unknown apk

Reputation: 141

Android: How to show progressbar on each imageview in griidview while sending multipal images to server

Hi I got frustrated while searching solution for my problem.My problem is that i have a gridview to show all images which i selected from gallery.I want to display progressbar on each images in gridview.and while uploading images to server using multipart i want too update progressbar..

I displayed progressbar on each imageview but i am unable to show progress on each progressbar.

SO please help me to show how to show progress bar and their respective process on each imageview.

thanks in advance

Upvotes: 2

Views: 847

Answers (2)

GPuschka
GPuschka

Reputation: 522

Create a interface for an observer:

interface ProgressListener {
  void onProgressUpdate(String imagePath, int progress);
}

Let the view holder implement that observer and know the image path:

public class ViewHolder implements ProgressListener {
   ImageView imgQueue;
   ProgressBar pb;
   TextView tv;
   String imagePath; //set this in getView!

   void onProgressUpdate(String imagePath, int progress) {
       if (!this.imagePath.equals(imagePath)) {
          //was not for this view
          return;
       }

       pb.post(new Runnable() {
         pb.setProgress(progress);
       });
   }

   //your other code
}

The adapter shall hold an map of observers for a particular image path/uri whatever and have an method that is called by the upload/download task. Also add methods to add and remove observer:

public class SelectedAdapter_Test extends BaseAdapter {
  private Map<String, ProgressListener> mProgressListener = new HashMap<>();

 //your other code

 synchronized void addProgressObserver(String imagePath, ProgressListener listener) {
    this.mListener.put(imagePath, listener);
 }

 synchronized void removeProgressObserver(String imagePath) {
   this.mListener.remove(imagePath);
 }

 synchronized void updateProgress(String imagePath, int progress) {
   ProgressListener l = this.mListener.get(imagePath);
   if (l != null) {
     l.onProgressUpdate(imagePath, progress);
   }
 }

 //other code
}

In getView of the adapter register the view holder as an observer:

public View getView(final int i, View convertView, ViewGroup viewGroup) {
  //other code

  holder.imagePath = data.get(i).getSdcardPath();

  this.addProgressObserver(holder.imagePath, holder);

  return convertView;
}

The problem right now is, that we register the observer but don't unregister. So let the adapter implement the View.addOnAttachStateChangeListener:

public class SelectedAdapter_Test extends BaseAdapter implements View.addOnAttachStateChangeListener {
  //other code
  void onViewAttachedToWindow(View v) {
    //We ignore this
  }

  void onViewDetachedFromWindow(View v) {
    //View is not visible anymore unregister observer
    ViewHolder holder = (ViewHolder) v.getTag();
    this.removeProgressObserver(holder.imagePath);
  }

  //other code
}

Register that observer when you return the view.

public View getView(final int i, View convertView, ViewGroup viewGroup) {
  //other code

  convertView.addOnAttachStateChangeListener(this);

  return convertView;
}

Finally you are able to tell the views what the progress is:

@Override
public void transferred(long num) {
   int progress = (int) ((num / (float) totalSize) * 100);
   selectedAdapter.onProgressUpdate(listOfPhotos.get(i).getSdcardPath(), progress);
}

One final problem remains, what if the activity is gone while the upload is in progress? You need to check if the activity is still alive. Maybe setting a flag in the adapter to true in onCreate and to false in onDestroy would do the trick. Then the last code fragment could check that flag and not notify the adapter on changes anymore.

So thats basically the idea of how to solve this. Does it work? I don't know I wrote it from scratch without any testing. And even if it does, you still have to manage the states when the progress is 0 or 100. But I leave that to you. Also you might want to change the BaseAdapter for an recyclerView so that we can get rid of the View.addOnAttachStateChangeListener.

Upvotes: 1

Aks4125
Aks4125

Reputation: 5720

  • add boolean in adapter class
    public SelectedAdapter_Test(Context c, ArrayList<CustomGallery> data, boolean showProgress) {
         mContext = c;
         inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         this.data = data;
         this.showProgress = showProgress;
    }
  • changes in Adapter class getView
        holder.pb = (ProgressBar) convertView.findViewById(R.id.progressbar);
        if (showProgress)
            holder.pb.setVisibility(View.VISIBLE);
        else
            holder.pb.setVisibility(View.GONE);
  • make changes in doFileUpload
private void doFileUpload(View v) {
View vi = v;
for (i = 0; i < listOfPhotos.size(); i++) {
          <--your task-->           
     }
 //**important**
 SelectedAdapter_Test mTest = new SelectedAdapter_Test(context,data,false);
 // set above adapter object respectively;
  mList.setadapter(mTest);
}

FYI. pass showProgress value as true for the first time when you set adapter.

Upvotes: 0

Related Questions