ductran
ductran

Reputation: 10203

Android Volley - Show progress bar in listview adapter when loading image

I tried to get image from network with Volley in listview item. While downloading image, the progress bar is showing, when complete, it should be hide.

Here is my adapter:

   public class NewsAdapter  extends CursorAdapter{
public NewsAdapter(Context context, Cursor c) {
    super(context, c, true);
}

@Override
public Cursor getItem(int position) {
    return (Cursor) super.getItem(position);
}

@Override
public void bindView(View view, final Context context, Cursor cursor) {
    final NetworkImageView imgNewsItem = (NetworkImageView) view.findViewById(R.id.imgNewsItem); 
    final ProgressBar progressNewsList = (ProgressBar) view.findViewById(R.id.progressNewsList);

    progressNewsList.setVisibility(View.VISIBLE);
    imgNewsItem.setVisibility(View.GONE);
    Ln.d("get news image: %s", cursor.getString(cursor.getColumnIndex(News.IMAGE_COLUMN)));
    ImageCacheManager.getInstance().getImageLoader().get(cursor.getString(cursor.getColumnIndex(News.IMAGE_COLUMN)), new ImageListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            Ln.e(error);
            progressNewsList.setVisibility(View.GONE);
            imgNewsItem.setVisibility(View.VISIBLE);
            imgNewsItem.setImageResource(R.drawable.news_default_image);
        }

        @Override
        public void onResponse(ImageContainer response, boolean isImmediate) {
            progressNewsList.setVisibility(View.GONE);
            imgNewsItem.setVisibility(View.VISIBLE);
            imgNewsItem.setImageBitmap(response.getBitmap());
        }
    });
}

@Override
public View newView(Context arg0, Cursor arg1, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View retView = inflater.inflate(R.layout.row_view, parent, false);
    return retView;
}

}

I have debugged and found that Volley download and cache image bitmap is ok, but the image view doesn't display.

My item layout look like this:

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp" >

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/imgNewsItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:src="@drawable/news_default_image"
      android:visibility="gone" />

    <ProgressBar
        android:id="@+id/progressNewsList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" 
        >
    </ProgressBar>
</LinearLayout>

The ImageCacheManager from this example: https://github.com/rdrobinson3/VolleyImageCacheExample Could you please tell me where I am wrong?. Thanks in advance.

Update: another, the progress bar isn't showed when downloading.

Upvotes: 3

Views: 12476

Answers (3)

Mina Fawzy
Mina Fawzy

Reputation: 21452

Change LinearLayout to FrameLayout and change order to make progress before networkimageview to be like this

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp" >

<ProgressBar
        android:id="@+id/progressNewsList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" 
        >
    </ProgressBar>

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/imgNewsItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:src="@drawable/news_default_image"
      android:visibility="gone" />


</FrameLayout>

Java Code

I am using in recycleview adapter

@Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
      ImageLoader _ImageLoader = MySingleton.getInstance(_Context).getmImageLoader();


        String url = "...."; // your image url
  holder.ProgressBar.setVisibility(View.VISIBLE);
            _ImageLoader.get(url, new ImageLoader.ImageListener() {
                @Override
                public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                    if (response.getBitmap() != null) {
                        holder.ProgressBar.setVisibility(View.GONE);
                        holder.imageView.setImageBitmap(response.getBitmap());
                    }

                }
                @Override
                public void onErrorResponse(VolleyError error) {

                }
            });
}

MySingleton Class

public class MySingleton {

    private static MySingleton mInstance;
    private Context mContext;
    private RequestQueue mResquestQueue;
    private ImageLoader mImageLoader;

    private MySingleton(Context mCtx){
        this.mContext = mCtx;
        mResquestQueue = Volley.newRequestQueue(MyApplication.getAppContext());
        mImageLoader = new ImageLoader(mResquestQueue , new ImageLoader.ImageCache(){
            private final LruCache<String , Bitmap> cache = new LruCache<>(20);

            @Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }

            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                   cache.put(url , bitmap);

            }
        });

    }

    public static synchronized MySingleton getInstance(Context context){
        if(mInstance == null){
            mInstance = new MySingleton(context);
        }
        return mInstance;

    }

    public RequestQueue getResquestQueue(){
        if(mResquestQueue == null){
            mResquestQueue= Volley.newRequestQueue(mContext.getApplicationContext());
        }
        return mResquestQueue;
    }

    public <T> void addToRequestQueue(Request<T> request){
          mResquestQueue.add(request);
    }

    public ImageLoader getmImageLoader(){
        return mImageLoader;
    }

    public void CancelAllRequestes(){
        if(mResquestQueue != null){
            mResquestQueue.cancelAll(this);
        }
    }

}

Upvotes: 1

Sushil
Sushil

Reputation: 41

If you are using method to load Image and ProgressBar has been intialized in different method then hiding ProgressBar on onResponse(...) may not work so you need to pass ProgressBar as parameter.

private void loadImage(String imageUrl, final ImageView imageView, final ProgressBar progressBar) {
    //progressBar.setVisibility(View.VISIBLE);
    if (imageUrl != null) {
        mImageLoader.get(imageUrl, new ImageLoader.ImageListener() {

            @Override
            public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                if (response.getBitmap() != null) {
                    progressBar.setVisibility(View.GONE);
                    imageView.setImageBitmap(response.getBitmap());
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("onErrorResponse ", error.toString());
                progressBar.setVisibility(View.GONE);
            }
        });
    }
}

Upvotes: 1

Marco RS
Marco RS

Reputation: 8245

You need to change ImageListener.onResponse method to the following:

@Override
public void onResponse(ImageContainer response, boolean isImmediate) {
    Bitmap bitmap = response.getBitmap();
    if(bitmap != null){
       progressNewsList.setVisibility(View.GONE);
       imgNewsItem.setVisibility(View.VISIBLE);
       imgNewsItem.setImageBitmap(bitmap);
   }
}

The following is the java doc for the ImageListener:

Interface for the response handlers on image requests. The call flow is this: 1. Upon being attached to a request, onResponse(response, true) will be invoked to reflect any cached data that was already available. If the data was available, response.getBitmap() will be non-null. 2. After a network response returns, only one of the following cases will happen: - onResponse(response, false) will be called if the image was loaded. or - onErrorResponse will be called if there was an error loading the image

Upvotes: 1

Related Questions