【第二篇】Volley的使用之加载图片

Volley加载图片有两种方式:
  1,ImageRequest 来对网络图片进行请求,放入请求队列,获取后现在在控件上面。
  2,NetworkImageView 最为自定义控件来自动加载网络图片。

  3,imageloader,对图片大小,质量格式控制来按需加载图片。
下面分别举例子说明使用:

ImageRequest的使用来加载图片:
首先设计界面,是个Gridview来加载图片:
activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
   <GridView android:id="@+id/gvImages"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:numColumns="3"       
       android:stretchMode="columnWidth"
       android:verticalSpacing="10dp" 
       android:horizontalSpacing="10dp">       
   </GridView>
</RelativeLayout>

GridViewitem布局文件如下,上面是图片,下面是文字说明:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView
        android:id="@+id/ivImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:contentDescription="test" />
    <TextView
        android:id="@+id/tvDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/ivImage"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

下面是主要的图片加载的逻辑代码,流程如下:

  1,创建请求队列mQueue;
  2,创建ImageRequest 请求,并进行配置,并将请求放入请求队列mqueue中去;
  3,ImageRequest只有一个构造方法:对图片大小和图片格式进行设置;

 /**
     * Creates a new image request, decoding to a maximum specified width and
     * height. If both width and height are zero, the image will be decoded to
     * its natural size. If one of the two is nonzero, that dimension will be
     * clamped and the other one will be set to preserve the image's aspect
     * ratio. If both width and height are nonzero, the image will be decoded to
     * be fit in the rectangle of dimensions width x height while keeping its
     * aspect ratio.
     *
     * @param url URL of the image 网络图片Url
     * @param listener Listener to receive the decoded bitmap 接收网络图片的bitmap回调参数
     * @param maxWidth Maximum width to decode this bitmap to, or zero for none 宽
     * @param maxHeight Maximum height to decode this bitmap to, or zero for 高
     *            none
     * @param decodeConfig Format to decode the bitmap to 编码质量的配置
     * @param errorListener Error listener, or null to ignore errors 加载图片失败的回调
     */
    public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
            Config decodeConfig, Response.ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        setRetryPolicy(
                new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
        mListener = listener;
        mDecodeConfig = decodeConfig;
        mMaxWidth = maxWidth;
        mMaxHeight = maxHeight;
    }
package com.soyoungboy.volleydemo;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.Volley;
/**
 * Volley使用demo
 * 
 * @author soyoungboy
 */
public class MainActivity extends Activity {
    private static final String[] URLS = {
        "http://img.my.csdn.net/uploads/201403/03/1393854094_4652.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854084_6138.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854084_1323.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854084_8439.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854083_6511.jpg",
    "http://img.my.csdn.net/uploads/201403/03/1393854083_2323.jpg" };
    private static final String[] DESCS = { "photo1", "photo2", "photo3",
        "photo4", "photo5", "photo6" };
    private RequestQueue mQueue;
    private GridView gvImages;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gvImages = (GridView) findViewById(R.id.gvImages);
        GridAdapter adpater = new GridAdapter();
        gvImages.setAdapter(adpater);
        mQueue = Volley.newRequestQueue(this);
    }
    class GridAdapter extends BaseAdapter {
        private LayoutInflater layoutInflater;
        public GridAdapter() {
            layoutInflater = LayoutInflater.from(MainActivity.this);
        }
        @Override
        public int getCount() {
            return URLS.length;
        }
        @Override
        public Object getItem(int position) {
            return URLS[position];
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = layoutInflater.inflate(R.layout.grid_item, null);
                viewHolder.ivImage = (ImageView) convertView
                        .findViewById(R.id.ivImage);
                viewHolder.tvDesc = (TextView) convertView
                        .findViewById(R.id.tvDesc);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            loadImgByVolley(URLS[position], viewHolder.ivImage);
            viewHolder.tvDesc.setText(DESCS[position]);
            return convertView;
        }
    }
    static class ViewHolder {
        ImageView ivImage;
        TextView tvDesc;
    }
    public void loadImgByVolley(String imgUrl, final ImageView imageView) {
        ImageRequest imgRequest = new ImageRequest(imgUrl,
                new Response.Listener<Bitmap>() {
            /**
             * 加载成功
             * @param arg0
             */
            @Override
            public void onResponse(Bitmap arg0) {
                imageView.setImageBitmap(arg0);
            }
        }, 300, 200, Config.ARGB_8888, 
        new ErrorListener() {
            //加载失败
            @Override
            public void onErrorResponse(VolleyError arg0) {
                imageView.setImageResource(R.drawable.ic_launcher);
            }
        });
        //将图片加载放入请求队列中去
        mQueue.add(imgRequest);
    }
}

效果:

NetworkImageView加载图片:
首先在布局中使用NetWorkImageView:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <com.android.volley.toolbox.NetworkImageView 
        android:id="@+id/load_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</RelativeLayout>

java代码里面实现:

package com.soyoungboy.volleydemo;
import android.app.Activity;
import android.os.Bundle;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;
public class NetworkImageViewActivity extends Activity {
    private NetworkImageView load_img;
    private ImageLoader imageLoader;
    private RequestQueue requestQueue;
    private LruImageCache lruImageCache;
    private static final String IMGURL = "http://imgsrc.baidu.com/forum/w%3D580/sign=f96acdfc08f79052ef1f47363cf1d738/cb2fc65c10385343223c39ce9213b07ecb808870.jpg";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_networkimageview);
        load_img = (NetworkImageView) findViewById(R.id.load_img);
        lruImageCache = LruImageCache.getInstance();
        requestQueue = Volley.newRequestQueue(this);
        imageLoader = new ImageLoader(requestQueue, lruImageCache);
        load_img.setImageUrl(IMGURL, imageLoader);
    }
}

LruImageCache.java缓存类:

package com.soyoungboy.volleydemo;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruImageCache implements ImageCache{

    private static LruCache<String, Bitmap> mMemoryCache;
    
    private static LruImageCache lruImageCache;
    
    private LruImageCache(){
        // Get the Max available memory
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap bitmap){
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };        
    }
    
    public static LruImageCache getInstance(){
        if(lruImageCache == null){
            lruImageCache = new LruImageCache();
        }
        return lruImageCache;
    }
    
    @Override
    public Bitmap getBitmap(String arg0) {        
        return mMemoryCache.get(arg0);    
    }

    @Override
    public void putBitmap(String arg0, Bitmap arg1) {
        if(getBitmap(arg0) == null){
            mMemoryCache.put(arg0, arg1);
        }        
    }

}


其中LruImageCache是个Lru算法类,主要用于处理缓存的大小问题,可以避免加载图片的时候oom的问题,ImaageLoader是volley提供的另外一种加载图片的方式。最后通过setImageUrl(String url, ImageLoader imageLoader)来进行加载。
NetworkImageView的优势在于他能够根据组件的大小自动进行图片的大小缩放处理。后面文章会在源码分析中进行讲解。
效果:

ImageLoader加载图片:
帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
  1,创建请求队列;
  2,创建imageloader对象,其中imageloader的构造方法第二个参数为imageCache的实现类,实现图片缓存的算法类。
  3,创建imagelistener对象,主要设置图片加载失败和加载过程中的图片设置。
界面如上面第一个的界面activity_main.xml;
这里主要看下逻辑:

package com.soyoungboy.volleydemo.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.Volley;
import com.soyoungboy.volleydemo.LruImageCache;
import com.soyoungboy.volleydemo.R;
public class ImageLoaderActivity extends Activity {
    private GridView gvImages;
    private static final String[] URLS = {
        "http://img.my.csdn.net/uploads/201403/03/1393854094_4652.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854084_6138.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854084_1323.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854084_8439.jpg",
        "http://img.my.csdn.net/uploads/201403/03/1393854083_6511.jpg",
    "http://img.my.csdn.net/uploads/201403/03/1393854083_2323.jpg" };
    private static final String[] DESCS = { "photo1", "photo2", "photo3",
        "photo4", "photo5", "photo6" };
    private RequestQueue mQueue;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gvImages = (GridView) findViewById(R.id.gvImages);
        mQueue = Volley.newRequestQueue(this);
        GridAdapter adpater = new GridAdapter();
        gvImages.setAdapter(adpater);
    }
    class GridAdapter extends BaseAdapter {
        private LayoutInflater layoutInflater;
        private ImageLoader imageLoader;
        public GridAdapter() {
            layoutInflater = LayoutInflater.from(ImageLoaderActivity.this);
            imageLoader = new ImageLoader(mQueue, LruImageCache.getInstance());
        }
        @Override
        public int getCount() {
            return URLS.length;
        }
        @Override
        public Object getItem(int position) {
            return URLS[position];
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = layoutInflater.inflate(R.layout.grid_item, null);
                viewHolder.ivImage = (ImageView) convertView
                        .findViewById(R.id.ivImage);
                viewHolder.tvDesc = (TextView) convertView
                        .findViewById(R.id.tvDesc);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            loadImgByVolley(URLS[position], viewHolder.ivImage);
            viewHolder.tvDesc.setText(DESCS[position]);
            return convertView;
        }
        private void loadImgByVolley(String string, ImageView ivImage) {
            ImageListener listener = ImageLoader.getImageListener(ivImage,
                    R.drawable.ic_launcher, R.drawable.ic_launcher);
            imageLoader.get(string, listener);
        }
    }
    static class ViewHolder {
        ImageView ivImage;
        TextView tvDesc;
    }
}

界面效果:

原文地址:https://www.cnblogs.com/androidsuperman/p/8a157b18ede85caa61ca5bc04bba43d0.html