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 件のコメント :
コメントを投稿