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