【Android】Volleyで通信をしよう(ImageLoader編)

Volley最後の記事はListView等でサーバから受け取った画像URLを次々に表示する方法を紹介します。

使うメリット

キャッシュもしてくれて画面外に出ていったらロードをキャンセルしてくれたり優秀です。

ソースコード

dependencies

compile 'eu.the4thfloor.volley:com.android.volley:2015.05.28'
public class AppController extends Application {

    public RequestQueue mRequestQueue;
    public ImageLoader mImageLoader;

    @Override
    public void onCreate() {
        super.onCreate();
        mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(getApplicationContext()));
    }
}

今回は画像なので、ImageLoaderを忘れないでください

Adapterクラス

public class ImageAdapter extends ArrayAdapter<ImageListModel> {

    private LayoutInflater mInflater;
    private ImageLoader mLoader;

    public ImageAdapter(Context context, int resource, List<ImageListModel> imageList) {

        super(context, resource, imageList);
        mInflater = LayoutInflater.from(context);
        mLoader = ((AppController)((MainActivity)context).getApplication()).mImageLoader;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        ImageListModel model = getItem(position);

        if (null == convertView) {
            convertView = mInflater.inflate(R.layout.line_layout, parent, false);
            holder = new ViewHolder();
            holder.image = (ImageView)convertView.findViewById(R.id.img_awn);
            holder.name = (TextView)convertView.findViewById(R.id.txt_name);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        ImageLoader.ImageContainer imageContainer = (ImageLoader.ImageContainer)holder.image.getTag();
        if (imageContainer != null) {
            imageContainer.cancelRequest();
        }

        ImageLoader.ImageListener listener = ImageLoader.getImageListener(holder.image, R.drawable.load, R.drawable.error);

        holder.image.setTag(mLoader.get(model.getImageUrl(), listener));
        holder.name.setText(model.getName());

        convertView.setTag(holder);

        return convertView;
    }

    private static class ViewHolder {
        ImageView image;
        TextView name;
    }
}

コンストラクタでImageLoaderのインスタンスを取得しておきます。
mLoader = *1.mImageLoader;

以下の処理で画像の取得をしています。
mLoader.get(model.getImageUrl(), listener)

上下に連続スクロールされた時のためにキャンセル処理も書きます。
ImageLoader.ImageContainer imageContainer = (ImageLoader.ImageContainer)holder.image.getTag();
if (imageContainer != null) {
imageContainer.cancelRequest();
}
上記キャンセル処理のためにImageViewのtagに画像取得を書いてました。
holder.image.setTag(mLoader.get(model.getImageUrl(), listener));

public class LruBitmapCache extends LruCache<String, Bitmap>
        implements ImageCache {

    public LruBitmapCache(int maxSize) {
        super(maxSize);
    }

    public LruBitmapCache(Context ctx) {
        this(getCacheSize(ctx));
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight();
    }

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

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

    // Returns a cache size equal to approximately three screens worth of images.
    public static int getCacheSize(Context ctx) {
        final DisplayMetrics displayMetrics = ctx.getResources().
                getDisplayMetrics();
        final int screenWidth = displayMetrics.widthPixels;
        final int screenHeight = displayMetrics.heightPixels;
        // 4 bytes per pixel
        final int screenBytes = screenWidth * screenHeight * 4;

        return screenBytes * 3;
    }
}

キャッシュクラスは公式の物です。

ListViewに表示するデータ作成など

    private List<ImageListModel> makeImageListModel() {

        List<ImageListModel> list = new ArrayList<>();
        ImageListModel model = null;

        for (int i=0; i<10; i++) {
            model = new ImageListModel();
            model.setImageUrl("http://www.acrowavenet.com/wp/wp-content/themes/acrowavenet/images/common/header_logo.png");
            model.setName("株式会社アクロウェーブネット");
            list.add(model);
        }

        return list;
    }
public class ImageListModel {

    private String imageUrl;
    private String name;

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

今回のソースコード一式は以下にあります。
https://github.com/k-shimoju/android/tree/master/Volley_ImageLoader

*1:AppController)((MainActivity)context).getApplication(