ViewがRefreshされる度に、画像を読み込みを行うとUsabilityが下がる。
このため一度取得したDataは内部でCacheし、再度取得に行かないように実装する。
また、取得した画像の横幅が、端末の横幅よりも広い場合は、画像をResizeする。
Android Studioで開発を行い、SourceはGitHubで公開している。
簡単に流れを下記に示す。
1. SimpleAdapterを継承したClass(ListTemplateAdapter)内のgetView()で、AsyncTaskを継承したClass(ImageGetTask)を呼び出し画像を取得する
imageView.setTag(thumbUrl); ImageGetTask task = new ImageGetTask(imageView, waitBar); task.execute(thumbUrl);
2. ImageGetTaskのdoInBackground内でCacheを確認し、空であればNetworkから画像を取得し、取得ができたらCacheに保存する
@Override protected Bitmap doInBackground(String... params) { synchronized (context){ try { Bitmap image = ImageCache.getImage(params[0]); if (image == null) { URL imageUrl = new URL(params[0]); image = getImage(imageUrl); ImageCache.setImage(params[0], image); } return image; } catch (MalformedURLException e) { return null; } } }
3. 画像を取得し、画面の横幅よりも大きい画像の場合は、Resizeを行う
private Bitmap getImage(URL imageUrl) { InputStream inputStream = null; if (imageUrl != null) { try { inputStream = (InputStream) imageUrl.getContent(); } catch (IOException e) { e.printStackTrace(); return null; } } Bitmap bitmap = BitmapFactory.decodeStream(inputStream); try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); return null; } DisplayMetrics metrics = MetrixCache.get(); if (metrics != null) { float scale = (float) bitmap.getWidth() / metrics.widthPixels; if (scale > 1) { int imageWidth = (int) (bitmap.getWidth() / scale); int imageHeight = (int) (bitmap.getHeight() / scale); bitmap = Bitmap.createScaledBitmap( bitmap, imageWidth, imageHeight, false); } } return bitmap; }
4. 取得した画像はクラス変数としてCacheする
public class ImageCache { private static HashMap<String,Bitmap> cache = new HashMap<String,Bitmap>(); public static Bitmap getImage(String key) { if (cache.containsKey(key)) { return cache.get(key); } return null; } public static void setImage(String key, Bitmap image) { cache.put(key, image); } public static void clearCache(){ cache = null; cache = new HashMap<String,Bitmap>(); } }
5. ImageGetTaskのonPostExecute内で画像を設定する
@Override protected void onPostExecute(Bitmap result) { if(tag.equals(image.getTag())){ if(result!=null){ image.setImageBitmap(result); } else{ image.setImageDrawable(context.getResources().getDrawable(android.R.drawable.ic_notification_clear_all)); } progress.setVisibility(View.GONE); image.setVisibility(View.VISIBLE); } }
0 件のコメント :
コメントを投稿