【问题标题】:Android Volley - Show progress bar in listview adapter when loading imageAndroid Volley - 加载图像时在列表视图适配器中显示进度条
【发布时间】:2015-12-15 21:04:20
【问题描述】:

我尝试在列表视图项中使用Volley 从网络获取图像。下载图片时显示进度条,完成后隐藏。

这是我的适配器:

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

}

我调试过,发现Volley下载缓存图片位图没问题,但是图片视图不显示。

我的项目布局如下所示:

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

此示例中的 ImageCacheManager:https://github.com/rdrobinson3/VolleyImageCacheExample 你能告诉我我错在哪里吗?提前致谢。

更新:另外,下载时不显示进度条。

【问题讨论】:

  • 老实说,我不明白你是如何遵循这个例子的?我认为您不应该调用加载程序的get。您是否尝试过:imgNewsItem.setImageUrl(&lt;url&gt;, ImageCacheManager.getInstance().getImageLoader());
  • 但是我需要监听器隐藏进度条。
  • 你为什么要隐藏ProgressBar,虽然你必须dismiss();它。
  • @GrIsHu 因为我没有显示进度对话框。下载图片时我只想要一个带有圆形的进度条。

标签: android android-listview android-volley


【解决方案1】:

您需要将 ImageListener.onResponse 方法更改为以下内容:

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

以下是 ImageListener 的 java 文档:

图像请求的响应处理程序接口。呼叫流程 是这样的: 1. 在附加到请求后,onResponse(response, true) 将被调用以反映任何已缓存的数据 可用的。如果数据可用, response.getBitmap() 将是 非空。 2. 网络响应返回后,只有其中一个 将发生以下情况: - onResponse(response, false) 将是 如果图像已加载,则调用。或 - onErrorResponse 将被调用,如果 加载图片时出错

【讨论】:

    【解决方案2】:

    如果您使用方法加载 Image 并且 ProgressBar 已在不同的方法中初始化,则在 onResponse(...) 上隐藏 ProgressBar 可能不起作用,因此您需要将 ProgressBar 作为参数传递。

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

    【讨论】:

    • 您的回答有问题。首先imageUrl.equals(null) 将抛出 NullpointerException 如果 imageUrl 为空,你应该使用imageUrl != null。其次,将 ProgressBar 作为参数传递没有任何意义,和我的 bindView 方法一样。
    • 我同意你的第一点,我编辑了我的答案。您的第二点,您只是在 bindview 方法中初始化和处理 ProgressBar,所以没有问题,但是如果您使用不同的方法并且您正在处理已在 bindview 中初始化的 ProgressBar,它将不起作用。
    【解决方案3】:

    LinearLayout更改为FrameLayout并更改顺序以在networkimageview之前取得进展

    <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 代码

    我在recycleview适配器中使用

    @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 类

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 1970-01-01
      • 2012-12-02
      • 1970-01-01
      相关资源
      最近更新 更多